مجموعة أزرار الاختيار
تطرح سؤالًا واحدًا له جواب واحد بالضبط من بين خيارات قليلة معروضة كلها دفعة واحدة: مجموعة من أزرار الاختيار تحمل القيمة المختارة، تحت تسمية تستطيع أن تقول إن الجواب مطلوب أو اختياري، مع وصف وخطأ واحد للمجموعة.
- الفئة
- الاختيار
- الرموز
comp.field-group- المستوى
- مركّب
- مبني من
- Field group, Radio button
- Web
tanrei-radio-groupschedule - SwiftUI
TanreiRadioGroupradio_button_unchecked - Jetpack Compose
TanreiRadioGroupradio_button_unchecked - Flutter
TanreiRadioGroupradio_button_unchecked - React Native
RadioGroupradio_button_unchecked
مولَّد من docs/status/status.json, specs/radio-group.spec.json
مجموعة من أزرار الاختيار لها اسم ووصف ووسم المطلوب
زر الاختيار لا يُستخدم وحده أبدًا. ومجموعة أزرار الاختيار تجعل عدة أزرار منه سؤالًا واحدًا: تعطي المجموعة اسمًا، وسطرًا يقول كيف يُجاب، وكلمة تقول هل تجب الإجابة، وسببًا واحدًا حين تُرفض الإجابة، وتحمل الجواب قيمةً واحدة.
تُبنى من مجموعة حقول و أزرار اختيار. مجموعة الحقول هي الإطار، في نوعها radio-group: التسمية، وعلامة المطلوب أو الاختياري، والوصف، والخطأ، والتخطيط في عمود أو صف، ومجموعة أزرار الاختيار الواحدة التي تُخبَر بها التقنيات المساعدة. وأزرار الاختيار تحمل القيمة: كل زر منها خيار له تسميته، والمحدَّد منها هو الجواب. ومجموعة أزرار الاختيار لا ترسم شيئًا من عندها وليس لها رمز تصميم (design token). وما تضيفه إلى الاثنين هو الحالة التي يكتبها كل منتج لولاها: قيمة واحدة تدخل وتخرج وحدث change واحد لها، ومفاتيح الأسهم وموضع التوقف الواحد في ترتيب التركيز محفوظة للمجموعة، ومكان في النموذج بصفتها عنصر تحكم واحدًا.
وعرضها عرض المكان الذي توضع فيه.
على الويب هي <tanrei-radio-group>. والمنصات الأخرى لم تنفّذها بعد.
<tanrei-radio-group label="التوصيل" name="delivery" value="standard" required required-text="مطلوب"
supporting-text="يمكنك تغييره إلى أن يُشحن الطلب.">
<tanrei-radio-button value="standard" label="عادي، من 3 إلى 5 أيام"></tanrei-radio-button>
<tanrei-radio-button value="express" label="سريع، في اليوم التالي"></tanrei-radio-button>
<tanrei-radio-button value="pickup" label="الاستلام من المتجر"></tanrei-radio-button>
</tanrei-radio-group>
<script type="module">
import '@tanrei/web/components/radio-group';
const group = document.querySelector('tanrei-radio-group');
group.addEventListener('change', (event) => {
// event.detail.value هي القيمة الجديدة؛ و group.value تحملها سلفًا.
});
</script>import { RadioButton, RadioGroup } from '@tanrei/react';
<RadioGroup label="التوصيل" value={delivery} onChange={(event) => setDelivery(event.detail.value)}
error={refused} errorText="التوصيل السريع لا يصل إلى هذا العنوان. اختر طريقة أخرى.">
<RadioButton value="standard" label="عادي، من 3 إلى 5 أيام" />
<RadioButton value="express" label="سريع، في اليوم التالي" />
<RadioButton value="pickup" label="الاستلام من المتجر" />
</RadioGroup>داخل مجموعة أزرار الاختيار لا يحتاج زر الاختيار إلى name ولا إلى checked: فالخاصية value في المجموعة تقول أيّ الأزرار هو المحدَّد.
المجموعة نفسها مكتوبةً باليد من عضويها هي الصورة نفسها، ومجموعة أزرار الاختيار نفسها عند التقنيات المساعدة. تُخبَر مجموعة الحقول بما فيها بالقيمة kind="radio-group"، وتحمل أزرار الاختيار اسمًا واحدًا في name:
<tanrei-field-group kind="radio-group" label="التوصيل"
supporting-text="يمكنك تغييره إلى أن يُشحن الطلب."
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-radio-button name="delivery" value="pickup" label="الاستلام من المتجر"></tanrei-radio-button>
</tanrei-field-group>المجموعة نفسها مكتوبةً باليد: مجموعة حقول نوعها radio-group، بداخلها أزرار اختيار لها اسم واحد
ما لا تفعله مجموعة الحقول وأزرار الاختيار المكتوبة باليد هو حمل الجواب. ولا يختلف شيء مما يُرسم أو يُقال.
| الجانب | الكتابة باليد | مجموعة أزرار الاختيار |
|---|---|---|
| الجواب | يقرؤه المنتج من أزرار الاختيار | الخاصية value، وحدث change واحد على عنصر واحد |
| تعيين الجواب | الخاصية checked على زر اختيار واحد |
value = "express" |
| ما يرسله النموذج | المُدخلة نفسها، من زر الاختيار المحدَّد | المُدخلة نفسها، من المجموعة |
| مجموعة مطلوبة تُركت بلا جواب | تُرسم وتُقال على أنها مطلوبة؛ والنموذج لا يرفضها | يرفضها تحقق النموذج نفسه |
| الخيار المحدَّد يُزال، أو لم يُعرض بعد | يضيع الجواب | تبقى value محفوظة |
| خيار محدَّد عطّلته أنت بمفرده | لا يرسل شيئًا | تُرسل قيمته |
| مفاتيح الأسهم، وموضع التوقف الواحد للمفتاح Tab، وموضع كل زر اختيار في المجموعة | هي نفسها، من أزرار الاختيار ذات الاسم الواحد | هي نفسها، من المجموعة |
اكتب مجموعة الحقول وأزرار الاختيار باليد حيث تحمل المجموعة بين خياراتها شيئًا لا تخطّطه مجموعة أزرار الاختيار، كسطر من عندك تحت كل خيار، أو حيث يجب أن تقف الخيارات في عناصر من عندك على نحو لا يتيحه المنفذ.
مجموعة مطلوبة بلا جواب في حالة خطأ، وجواب مرفوض، وترتيب في صف، ومجموعة فيها خيار معطَّل
البنية
| الجزء | الوصف |
|---|---|
1 field-group | The field group, in its radio-group kind: the label with its requirement mark, the description under it, the column or the row the options stand in, and the error text below the last option — and the one radio group that assistive technology is told of. The field group itself, with its own tokens, not a drawing of it. |
2 radio-button | The radio buttons of the set, in the order given: the product's own, each the Radio button component with its own label, drawn from its own tokens. Which of them is selected is the group's value. |
الخصائص
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
value | string | "" | The value of the selected radio button; the empty string while none is selected. The radio group sets it when a person selects an option, and emits change; the product may also set it. |
label | string | "" | Names the set, visibly and to assistive technology: the question its controls answer ("Notify me by"). Required. — Field group |
labelHidden | boolean | false | Does not draw the label, which stays the accessible name of the group. For a set whose visible heading is elsewhere. — Field group |
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. — Field group |
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. — Field group On the web it is also what the form's own validation says of a required group left unanswered, where the browser has no sentence of its own for it (RGP-9). |
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. — Field group The radio group is exposed as invalid, and its radio buttons are drawn as they are: a radio button has no error condition (RGP-8). |
disabled | boolean | false | Disables every control of the set and draws the frame as disabled. — Field group The value is kept, and on the web it is not submitted (RGP-7, RGP-9). |
readOnly | boolean | false | Shows the answer and keeps it: the group can be focused and its options read, its value is submitted, but the person cannot change it (RGP-20). |
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. — Field group exposes the radio group as required, and on the web an empty value is reported to the form's own validation (RGP-9, RGP-10). |
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. — Field group |
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. — Field group |
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. — Field group Not part of the radio group's description: its required state carries it (RGP-10). |
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. — Field group |
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. — Field group The arrow keys are the same in both (RGP-5). |
الأحداث
| الحدث | الوصف |
|---|---|
change | The person selected another option; carries the new value, which the group already holds. Emitted once per selection, by the group and not by its radio buttons. Not emitted when the product sets value, or when the selected option is activated again. |
العناصر
أنواع العناصر التي يكررها المكوّن. يسرد كل نموذج اختبار عناصره بالترتيب، وتسمّي كل منصة كل نوع بأسلوبها.
radio-button
An option of the set: the radio button component with its own label, selected by the group's value, placed, spaced and disabled by the group, otherwise drawn and pressed as it is anywhere.
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
value | string | "" | What the option stands for, as the Radio button's value: the group's value while this option is the selected one. Unique in the group and not empty. |
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, and is then skipped by the arrow keys. |
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| العنصر | tanrei-radio-button | TanreiRadioButton | TanreiRadioButton | TanreiRadioButton | RadioButton |
value · الخاصية | value | value | value | value | value |
label · الخاصية | label | title | label | label | label |
disabled · الخاصية | disabled | disabled | enabled | enabled | disabled |
| ملاحظات | A tanrei-radio-button child without a name: inside a tanrei-radio-group it takes its group, its checked, its tab stop and its position from the group and submits nothing itself (RAD-25). |
الحالات
السلوك
متطلبات بصيغة EARS. يُختبر تنفيذ كل منصة مقابل هذه المعرّفات. يُعرض نص المتطلبات كما ورد في ملف المواصفة، بالإنجليزية.
| المعرّف | المتطلب |
|---|---|
RGP-1 | THE radio group SHALL be a field group whose kind is radio-group and whose spacing is controls, around its radio buttons: the field group itself, with the field group's own tokens, measures and sentences, and no copy of it — its rows, their order and their gaps (FGR-1), the label above the options (FGR-2), the requirement and its mark (FGR-4, FGR-5, FGR-6), the description under the label, which stays while the group is in error (FGR-7), the error text below the last option (FGR-8) and the disabled frame (FGR-14), each from the prop of the same name, which is the field group's. It SHALL have no look and no token of its own: it SHALL draw no container, edge, fill or elevation, SHALL add no padding around its rows and no distance between its radio buttons but the field group's, and SHALL leave each radio button drawn from the radio button's own tokens, at the radio button's own size. |
RGP-2 | THE radio group SHALL lay out its radio buttons as the field group lays out its controls: WHILE orientation is vertical in one column in the order given (FGR-3), and WHILE orientation is horizontal in a row from the start edge that wraps onto further lines and never cuts, scrolls or narrows an option below what its content needs (FGR-13). The order given is the order of reading, of the arrow keys (RGP-5) and of each option's position (RGP-10) in both orientations. |
RGP-3 | THE radio group SHALL hold one value and show as selected the radio button whose value equals it, and no other; WHILE value is the empty string none SHALL be selected. WHEN the product sets value THE radio group SHALL select the radio button of that value and unselect the others (RAD-3), over the radio button's own selection motion (RAD-15), without emitting change and without moving focus. WHEN the product sets checked on one of the group's radio buttons THE radio group SHALL take that radio button's value as its value, likewise without emitting change, so that the two never disagree; WHEN the product takes checked off the radio button that value selects THE radio group SHALL keep value and show that radio button selected again at once, because the empty string is the one way to say that none is selected. A radio button that comes to the group checked — with the group or after it — SHALL give the group its value only WHILE value is the empty string, the last of several such; WHILE value is not empty, value SHALL decide and the mark SHALL be overruled. IF value equals no radio button's value THEN THE radio group SHALL show none selected, SHALL keep value as it was given, and in debug builds SHALL report it; IF two radio buttons carry one value THEN the first in the order given SHALL be the one value selects; IF a radio button carries the empty string THEN it SHALL never be shown selected, and a person's activation of it SHALL change nothing and emit nothing, because its selection would say that none is selected; in debug builds THE radio group SHALL report either. |
RGP-4 | WHEN the person selects a radio button of the group that was not selected — by pointer, touch, Space, a click on its label, an arrow key (RGP-5) or assistive technology, as RAD-1 says of the radio button — THE radio group SHALL set value to that radio button's value and emit change exactly once, carrying the new value, with value already set when the event is received; the radio button that was selected before SHALL become unselected and emit nothing (RAD-3), and nothing the selected radio button emits SHALL reach a listener on the group as a second change. WHEN the person activates the radio button that is already selected THE radio group SHALL keep value and emit nothing (RAD-2): a person cannot clear a radio group, and a question that may go unanswered has an option that says so. |
RGP-5 | WHEN one of the group's radio buttons has keyboard focus and the person presses Down Arrow or Right Arrow THE radio group SHALL move focus to the next enabled radio button in the order given, wrapping from the last to the first, and select it as RGP-4 says; Up Arrow and Left Arrow SHALL do the same towards the previous one, wrapping from the first to the last; in a right-to-left layout Right Arrow SHALL move to the previous and Left Arrow to the next, and Up Arrow and Down Arrow SHALL stay as they are. The four keys SHALL do this in both orientations, and by the order given, not by the place a wrapped row gave an option. THE radio group SHALL skip a disabled radio button, SHALL do nothing WHILE the focused one is the only enabled one, and SHALL leave a key pressed with Alt, Control or Meta to the platform. This is RAD-4, kept by the group for its radio buttons. |
RGP-6 | THE radio group SHALL keep exactly one of its radio buttons in the focus order: the selected one WHILE it is enabled, otherwise the first enabled one in the order given; Tab and Shift+Tab SHALL enter the group at that radio button from either side and SHALL leave the group from whichever radio button has focus, never moving within it (RAD-5). THE radio group SHALL NOT be a stop itself, and a press on its label, its requirement mark, its description or its error text SHALL select nothing and move no focus into the group (FGR-12). WHEN the radio button that is the stop changes while focus is inside the group THE radio group SHALL leave focus where it is. WHILE no radio button is enabled the group SHALL have no stop. WHEN the product asks the group itself for focus, where the platform has such a call, THE radio group SHALL give focus to the radio button that is the stop. |
RGP-7 | WHILE disabled is true THE radio group SHALL draw its frame from the field group's disabled tokens (FGR-14), SHALL make every radio button it holds disabled as the radio button's own disabled does (RAD-6, RAD-10) — not focusable, not operable, drawn disabled, the selected one still shown selected — SHALL emit no change, SHALL keep value, and SHALL be exposed as disabled, its texts still readable by assistive technology. WHILE disabled is false THE radio group SHALL NOT enable a radio button the product disabled itself: that one stays out of the focus order and of the arrow keys (RGP-5, RGP-6) and is still shown selected WHILE value is its value. |
RGP-8 | THE radio group SHALL take from required and optional what the form asks of the set, as a field group does (FGR-4), and SHALL NOT set the error condition itself because an answer is missing or for any other reason: error and errorText are the product's to set. WHILE error is true THE radio group SHALL draw errorText and the error parts of its frame (FGR-8), SHALL be exposed as invalid (RGP-10), and SHALL have every radio button it holds, selected or not, drawn in the radio button's own error form (RAD-26), as a field group in error marks each control that has an error condition (FGR-8): the refusal is the set's, said by the words below it and by the group's invalid state, and shown on every option, because any of them may be the answer that puts it right. A disabled radio button SHALL be drawn as disabled, without the error color (RAD-26), and THE radio group SHALL NOT expose a radio button as invalid or describe it by errorText: the group says both once (RGP-10). WHEN error becomes true, or errorText changes while error is true, and focus is on one of the group's radio buttons THE radio group SHALL have assistive technology announce errorText once, politely, and SHALL NOT move focus (FGR-9). A change of value SHALL NOT clear error. |
RGP-9 | WHERE the platform has forms that submit named values (the web) THE radio group SHALL take part in its form as one control: it SHALL submit value under its own name WHILE value is not the empty string and the group is not disabled, and nothing otherwise — also WHILE the radio button of that value is one the product disabled by itself, because the value is the group's and a radio button's disabled says who may change it; SHALL return to the value it was first given WHEN the form is reset, without emitting change; SHALL be disabled WHILE the form disables the set it is in; SHALL report a missing value to the form's own validation WHILE required is true and value is the empty string, in the platform's own words for an unanswered set of radio buttons where it has them, and otherwise in errorText, else requiredText, else label — never in words of Tanrei's; and its radio buttons SHALL submit nothing of their own. Enter on a focused radio button SHALL be left to the form (RAD-1). WHERE the platform has no such forms value and change are the whole of it. |
RGP-10 | THE radio group SHALL be exposed to assistive technology as the field group it is, in its radio-group kind, and SHALL add no group to it (FGR-25): one 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; read-only WHILE readOnly is true (RGP-20); saying its orientation where the platform's radio group has one; and described by, in this order, supportingText, errorText WHILE error is true, and optionalText WHILE optional is true, each new text exposed at once WHEN it changes (FGR-11). requiredText SHALL NOT be part of the description, because the required state carries it, and the requirement tag and the asterisk SHALL be kept from assistive technology as drawn parts. Each radio button SHALL expose its role, its checked state, its position in the group and the group's size as RAD-16 says, counted in the order given with disabled options included. WHERE the platform forms a radio group with a container of its own THE radio group SHALL be that container and SHALL NOT expose a second group around it. WHILE label is empty THE radio group SHALL still render and in debug builds report that the set has no accessible name (FGR-10). |
RGP-11 | WHEN a radio button is added to the group, removed from it or moved, or its value or its disabled changes, while the group is shown THE radio group SHALL lay out its radio buttons again at once, without a motion; SHALL select by value again (RGP-3), so that a radio button that arrives with the group's value is shown selected and value is kept WHEN the selected one leaves; SHALL give the disabled state it holds (RGP-7) to one that came and take it back from one that left; SHALL set the tab stop (RGP-6) and each position (RGP-10) again; SHALL emit no change; and SHALL leave focus on the radio button that has it. |
RGP-12 | THE radio group SHALL hold radio buttons and nothing else that can be operated. IF it holds no radio button THEN THE radio group SHALL draw its rows without one and in debug builds report it; IF it holds another control, or a radio button that names a group of its own (RAD-25), THEN in debug builds THE radio group SHALL report it. THE radio group SHALL NOT restyle a radio button or change how it answers hover, focus or a press: those stay the radio button's (RAD-7, RAD-8, RAD-11 to RAD-13). |
RGP-13 | WHILE the text size is enlarged THE radio group SHALL grow with its texts as a field group does (FGR-16): the label, the description, the error text and each option's label wrap and never clip, the requirement tag grows with its text, a horizontal row wraps and at 200% becomes a column where one line no longer holds two options (RGP-2), and no text SHALL be lost, lie over another part or need scrolling in two directions. |
RGP-14 | 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 radio group SHALL draw its frame as a field group does there (FGR-17) — its texts in the platform's text color, its requirement tag with an edge — and SHALL rely on no color of its own to show an error: the error is carried by the words of errorText and by the invalid state (RGP-10), and its radio buttons are drawn there as out of error (RAD-27). |
RGP-15 | WHERE the layout direction is right-to-left THE radio group SHALL mirror its layout as a field group does (FGR-18): the label row, the description, the options 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 option at the right; a column keeps its order from top to bottom. Each radio button mirrors itself (RAD-17), and Left Arrow and Right Arrow exchange what they do (RGP-5). |
RGP-16 | THE radio group SHALL take its layout direction from where it is used and SHALL have no direction setting of its own, as the field group (FGR-19) and each radio button (RAD-22) do; WHEN that direction changes while the radio group is shown THE radio group SHALL be drawn for the new direction at once, without a motion of its own, keeping its value, its selection and its focus, and the arrow keys SHALL follow the new direction at the next key (RGP-5). |
RGP-17 | THE radio group SHALL lay out its label, its description, its error text and the text of its requirement tag as the field group does (FGR-21): each as text of its own direction, isolated from the text around it, and placed and aligned by the layout direction, not by the text's own. Each option's label is the radio button's (RAD-23). |
RGP-18 | WHEN requiredMark or orientation names a value the radio group does not know THE radio group SHALL do with it what the field group does (FGR-22) — render with the prop's default (auto, vertical) — and in debug builds the unknown value SHALL be reported once. |
RGP-19 | THE radio group SHALL have no words of its own: requiredText and optionalText are the field group's, read as FGR-24 says — from the instance's prop and, WHILE that is empty, from the product's words of the same name, and from nowhere else. IF neither gives requiredText WHILE required is true and the required mark is tag THEN THE radio group SHALL show the asterisk of FGR-6 in the tag's place, as the field group does, and SHALL keep its required state (RGP-10), which needs no word. IF neither gives optionalText WHILE optional is true THEN THE radio group SHALL show no tag and SHALL add nothing to the description for it. In debug builds the missing words SHALL be reported once. |
RGP-20 | WHILE readOnly is true and disabled is false THE radio group SHALL make every radio button it holds read-only as the radio button's own readOnly does (RAD-28), without changing the readOnly the product gave any of them: the person can enter the group at its stop, which stays the selected radio button (RGP-6), move focus among its enabled radio buttons with the arrow keys as RGP-5 says while selecting none, and read each one's label, checked state and position, and cannot change value by any input. THE radio group SHALL then emit no change, SHALL keep value, SHALL be exposed as read-only beside its other states (RGP-10), SHALL be submitted with its form as RGP-9 says, SHALL NOT report a missing value to the form's own validation, because the person cannot give one, and SHALL draw its frame and its radio buttons from their enabled tokens, never the disabled ones. WHILE disabled is true as well, disabled wins (RGP-7). |
RGP-21 | 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 radio 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 radio group of the field group it is (RGP-10) — 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 radio group owns (aria-label, aria-labelledby, aria-disabled, aria-required, aria-invalid, aria-errormessage, aria-readonly), which it SHALL move and not expose: its name is label and its states are its props (RGP-10, RGP-20). 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 radio group SHALL take it off that element. WHEN the product sets an aria- attribute the radio group owns THE radio group SHALL report it in debug builds. |
مطابقة الأسماء بين المنصات
التكافؤ لا يعني واجهات برمجية متطابقة. تعبّر كل منصة عن العقد نفسه بأسلوبها.
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| المكوّن | tanrei-radio-group | TanreiRadioGroup | TanreiRadioGroup | TanreiRadioGroup | RadioGroup |
value · الخاصية | value | selection | value | groupValue | value |
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 |
readOnly · الخاصية | readOnly | readOnly | readOnly | readOnly | readOnly |
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 |
change · الحدث | change | selection | onValueChange | onChanged | onValueChange |
| ملاحظات | <tanrei-radio-group label="Delivery" name="delivery" value="express"><tanrei-radio-button value="standard" label="Standard"></tanrei-radio-button>…</tanrei-radio-group>; class TanreiRadioGroup; in @tanrei/react, RadioGroup with value and onChange. Composed in the construction the checkbox group has: the members that hold the value are the product's own children. The shadow root holds one <tanrei-field-group part="field-group" kind="radio-group" spacing="controls"> — the member's own element, not drawing code shared with it — around a <slot>; the radio buttons stay in the product's light DOM and are assigned through the group's slot into the field group's. The eleven props that are the field group's are set on that element as they are given, and its documented parts — label, requirement-label, supporting-text, error-text — are exported under its own names (exportparts); the group writes none of its custom properties, so --tanrei-comp-field-group-* set on the host is inherited by the field group inside. The radio group that assistive technology is told of is the field group's own element in its radio-group kind — name, description, required, invalid, disabled and orientation, once (FGR-25): the host has no role, and nothing is tied across a shadow root. The field group gives disabled to each radio button by the tanrei-field-connect event it already answers — a slotted radio button's event passes the field group on its composed path before it reaches the host — and writes the announcement of RGP-8. The host takes disabled from outside by itself — from a field group around it (FGR-15) and from <fieldset disabled> — and gives the field group inside the three together; the inner field group's own question to a group around it is stopped at the host, so that an outer field group counts one member, the radio group (a frame's question, by contrast, leaves). What the host keeps is what a frame cannot do. A form-associated custom element (static formAssociated = true): name is a web attribute, not a spec prop; the value attribute is the first value and what a reset returns to, the value property is the live one; it submits value, restores it on navigation (formStateRestoreCallback), follows <fieldset disabled> and reports valueMissing while required and value is empty, anchored on the radio button that is the tab stop, with the browser's own message for an unanswered set of radio buttons, in the browser's language — a required native radio button is asked once — and, where a browser gives none, errorText, else the required text, else label. A radio button finds its group with closest('tanrei-radio-group') when it connects; the group's radio buttons are those among its descendants whose nearest radio group it is — direct children or deeper, inside the product's own elements — found again when its child list changes (a MutationObserver: slotchange does not fire for a change below a slotted element); a radio button inside a shadow root of the product's own is found by neither side and groups by its name there. The group sets each option's checked, and its radio buttons take their tab stop, aria-posinset and aria-setsize from it again whenever its options change (RGP-11); it handles the arrow keys on the host. A radio button's own disabled attribute is never written, so an enabled group cannot enable what the product disabled. A radio button inside a group fires no input and no change at all — stopped at the group they would still pass a capture listener on an ancestor — it tells its group, which sets value and fires input and one change, a bubbling CustomEvent whose detail.value is the value; a listener set on a radio button inside a group hears nothing. A press on the frame's texts selects nothing and moves no focus into the group (RGP-6); the browser's own answer to a press on plain text — focus leaves what had it — is not prevented, because preventing it would prevent selecting the text. The host is not focusable and does not delegate focus, because its controls are light-DOM children; focus() moves to the radio button that is the stop. Radio buttons with one name and no tanrei-radio-group still form a group by themselves (RAD-25); inside a <tanrei-field-group kind="radio-group"> they are this component one level down. Attributes are kebab-case: label-hidden, supporting-text, error-text, required-mark, required-text, optional-text. The host is display: block. Without script the element is not defined and draws nothing of its own, as every Tanrei element with a shadow root; a page that must work without script writes a native fieldset of native radio buttons of one name, which submits the same entry. Words: the element has no words of its own; required-text and optional-text left empty read the product's words through the field group. Its field group gives each radio button the error condition, and the radio button draws its error form (RGP-8, FGR-8, RAD-26). readOnly is the readonly attribute: each radio button it holds is read-only while it is (their own readonly unchanged), the arrow keys move focus without selecting, and aria-readonly is written on the field group's radiogroup element, beside the other states it carries. | TanreiRadioGroup("Delivery", selection: $delivery, supportingText:, errorText:, error:, required:, optional:, orientation:) { TanreiRadioButton("Standard", value: Delivery.standard) … }, generic over a Hashable value: selection is a Binding<V?>, nil for none, and writing it is the change event. This is the container the radio button already uses to form a group on this platform (its name), which so far drew nothing; it gains the frame, which is the platform's field group itself in its radio-group kind (FGR-25), and the radio buttons inside read the selection from it. labelHidden follows .labelsHidden() and disabled follows .disabled(_:). The options are laid out by the field group's Layout (a column, or a row that wraps). iOS has no radio group trait: the container is .accessibilityElement(children: .contain) with the label and the description as its label and hint, and required and invalid are added to the hint in words. No forms: RGP-9 does not apply. The product's words are read from the \.tanreiWords environment value. Not built on this platform yet: in error every option is drawn in its error form (RGP-8, RAD-26). | TanreiRadioGroup(label = "Delivery", value = delivery, onValueChange = { delivery = it }, supportingText = …, isError = …, required = …, optional = …, orientation = …) { TanreiRadioButton(value = "standard", label = "Standard") … }: controlled, as Compose is — the group calls onValueChange and the caller moves value. The content runs in a TanreiRadioGroupScope whose TanreiRadioButton(value, label) takes selected and its click from the group; the group is built around TanreiFieldGroup in its radio-group kind (FGR-25), which applies Modifier.selectableGroup() itself, so the product does not, and has the name, the description and the error in its semantics. enabled is the inverse flag. A Column or a FlowRow. The bare TanreiRadioButton(selected, onClick) inside a selectableGroup() stays for options that are not laid out by a group (RAD-25). No forms: RGP-9 does not apply. The product's words are read from LocalTanreiWords. Not built on this platform yet: in error every option is drawn in its error form (RGP-8, RAD-26). | TanreiRadioGroup<T>(groupValue:, onChanged:, labelText: 'Delivery', helperText: …, errorText: …, isError: …, required: …, optional: …, orientation: …, children: [TanreiRadioButton<T>(value:, label:), …]). This is the TanreiRadioGroup<T> the radio button already stands in on this platform, which so far drew nothing and took a semanticLabel; it gains the frame, which is the platform's field group itself in its radio-group kind (FGR-25), and labelText with labelHidden replaces semanticLabel. groupValue is nullable for none; enabled is the inverse flag. A Column or a Wrap; the radio-group semantics, the arrow keys and the single tab stop stay where they are. FormField integration is the product's: RGP-9 does not apply. The product's words are read from the TanreiWords inherited widget, which the app fills from its own localizations. Not built on this platform yet: in error every option is drawn in its error form (RGP-8, RAD-26). | <RadioGroup label="Delivery" value={delivery} onValueChange={setDelivery} supportingText="…"><RadioButton value="standard" label="Standard" />…</RadioGroup>: controlled. This is the RadioGroup parent the radio button already uses on this platform, which so far drew nothing; it gains the frame, which is the platform's field group itself in its radio-group kind (FGR-25), and takes selected and onSelect off its children: an option inside reads both from the group's context. accessibilityRole="radiogroup" with accessibilityLabel and accessibilityHint; required and invalid are said in the hint, because React Native has neither state for a group. A column, or a row with flexWrap. Follows the app's direction where an ancestor's is not known. No forms: RGP-9 does not apply. The product's words are read from the TanreiWordsProvider context. Not built on this platform yet: in error every option is drawn in its error form (RGP-8, RAD-26). |
الرموز
| الرمز | يشير إلى | القيمة المحلولة (فاتح) |
|---|---|---|
--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 |
نماذج الاختبار
عروض مرجعية. تلتقط كل المنصات لقطة لكل نموذج بالمعرّف نفسه حتى يمكن مقارنة النتائج.
default
value: standard label: Delivery items: 3 none-selected
label: Delivery items: 3 supporting
value: express label: Delivery supportingText: You can change this until the order ship… items: 3 label-hidden
value: standard label: Delivery labelHidden: true supportingText: You can change this until the order ship… items: 3 required
value: standard label: Delivery supportingText: You can change this until the order ship… required: true requiredText: Required items: 3 optional
label: Delivery optional: true optionalText: Optional items: 3 required-asterisk
value: standard label: Delivery required: true requiredMark: asterisk items: 3 required-error
label: Delivery errorText: Choose how the order reaches you. error: true required: true requiredText: Required items: 3 error-selected
value: express 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 items: 3 error-one-disabled
value: express 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 items: 3 horizontal
value: m label: Size orientation: horizontal items: 3 horizontal-many
value: fri label: Send the report supportingText: One report, on the day you choose. orientation: horizontal items: 9 disabled
value: standard label: Delivery supportingText: You can change this until the order ship… disabled: true required: true requiredText: Required items: 3 one-disabled
value: standard label: Delivery items: 3 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 items: 3 required-ja
value: standard label: 配送方法 supportingText: 発送されるまで変更できます。 required: true requiredText: 必須 items: 3 error-ja
label: 配送方法 errorText: 配送方法を選んでください。 error: true required: true requiredText: 必須 items: 3 rtl
value: express label: طريقة التوصيل supportingText: يمكنك تغيير هذا حتى يُشحن الطلب. required: true requiredText: مطلوب direction: rtl items: 3 horizontal-rtl
label: גודל errorText: יש לבחור גודל. error: true required: true requiredText: חובה orientation: horizontal direction: rtl items: 3 ltr-label-rtl
value: 5 label: Wi-Fi 6E supportingText: 2.4 GHz, 5 GHz, 6 GHz direction: rtl items: 3 مولَّد من specs/radio-group.spec.json, tokens/comp/field-group.tokens.json, design/tokens/
ليست لمجموعة أزرار الاختيار رموز خاصة بها. والجدول أعلاه يسرد رموز مجموعة الحقول، وهي التي ترسم إطارها: فنظام التصميم الذي يعيد تنسيق مجموعة الحقول يعيد معها تنسيق كل مجموعة أزرار اختيار. وكل زر اختيار يُرسم من رموز زر الاختيار نفسه.
| ما يُرسم | لمن هو |
|---|---|
| التسمية، وعلامة المطلوب أو الاختياري، والوصف، ونص الخطأ، والمسافات بين الصفوف وبين أزرار الاختيار | لمجموعة الحقول، من comp.field-group.* |
| كل زر اختيار: الحلقة، والتعبئة، والتسمية، وطبقة الحالة، وحلقة التركيز، وهيئة التعطيل | لزر الاختيار، من comp.radio-button.* |
| أي شيء آخر | لا شيء: مجموعة أزرار الاختيار لا ترسم شيئًا |
نظام التصميم ينسّق الإطار مرة واحدة، لكل مجموعة حقول ومجموعة أزرار اختيار ومجموعة خانات اختيار. والمثيل الواحد يُخصَّص على المثيل نفسه: على الويب، رمز من رموز مجموعة الحقول يُعيَّن على مجموعة أزرار الاختيار يبلغ الإطار الذي بداخلها.
<tanrei-radio-group label="التوصيل"
style="--tanrei-comp-field-group-gap-controls: 12px">…</tanrei-radio-group>- جذر الظل (shadow root) في العنصر فيه عنصر
<tanrei-field-group kind="radio-group">حول منفذ. وأزرار الاختيار تبقى عناصرك الفرعية أنت. واستيراد العنصر يعرّف العضوين كليهما. - العنصر مرتبط بالنماذج (form-associated). يأخذ
nameوform، ويرسلvalueتحت الاسمname، حتى حين يكون زر الاختيار المحدَّد زرًّا عطّلته أنت بمفرده. وأزرار الاختيار فيه لا ترسل شيئًا، أيًّا كانnameالذي تحمله. ويعود عند إعادة الضبط إلى قيمة خاصية HTMLvalue، ويتبع عنصر<fieldset>المعطَّل، ويبلّغ بأن القيمة ناقصة ما دامتrequiredمعيَّنة وvalueفارغة، بكلمات المتصفح نفسه لمجموعة أزرار اختيار بلا جواب. - الحدث
changeهو CustomEvent قيمته الجديدة فيdetail.value؛ ويصدر الحدثinputقبله. والمستمع الموضوع على زر اختيار داخل المجموعة لا يسمع أيًّا منهما. - الأجزاء:
field-groupهو الإطار، ولأجزائه هنا الأسماء نفسها التي لها في المستوى الأدنى:label،requirement-label،supporting-text،error-text. وأزرار الاختيار التي من عندك تُنسَّق كما تُنسَّق في أي مكان، بالمحدِّدtanrei-radio-button::part(…). - العنصر نفسه غير قابل للتركيز. فالدالة
focus()تذهب إلى زر الاختيار الذي هو موضع التوقف، وعنصر<label for>من عند الصفحة ينقل التركيز إليه. - ليس للعنصر دور: فمجموعة أزرار الاختيار هي مجموعة الحقول التي بداخله. سمِّه بالخاصية
label، ومعهاlabel-hiddenحيث تُرسم التسمية في مكان آخر، ولا تسمِّه أبدًا بالخاصيةaria-label، فهي لا تسمّي شيئًا هنا. - خصائص HTML تُكتب بصيغة kebab-case:
label-hidden،supporting-text،error-text،required-mark،required-text،optional-text. - قبل أن يُعرَّف العنصر، ومن دون سكربت، لا يُرسم شيء من عنده: تظهر أزرار الاختيار محتوى عاديًّا. والصفحة التي يجب أن تعمل بلا سكربت تكتب عنصر
<fieldset>أصليًّا فيه أزرار اختيار أصلية لهاnameواحد، وهو يرسل المُدخلة نفسها.
| الشخص | استخدم |
|---|---|
| يعطي قيمة واحدة من خيارات قليلة تستحق كلها أن تُرى دفعة واحدة، حتى خمسة تقريبًا، في نموذج أو إعداد | مجموعة أزرار اختيار. |
| يغيّر ما يُعرض تحته: أيّ عرض، أيّ عيّنة، أيّ فترة | علامات التبويب. |
| يعطي قيمة واحدة من خيارات كثيرة، أو يضيق المكان | عنصر اختيار. |
| يعطي عدة قيم جوابًا واحدًا | مجموعة خانات اختيار. |
| يكتب المجموعة نفسها باليد، ليرتّبها على نحو لا تقدّمه مجموعة أزرار الاختيار | مجموعة حقول قيمة kind فيها radio-group، حول أزرار اختيار لها اسم واحد (مستوى واحد إلى الأسفل). |
| يشغّل شيئًا واحدًا أو يوقفه، فورًا | مفتاح تبديل. |
| يضغط أزرارًا متجاورة يُبدَّل كلٌّ منها بمفرده | مجموعة أزرار. |
الفيصل بين مجموعة أزرار الاختيار وعلامات التبويب هو ما يفعله الاختيار، لا مظهره: القيمة التي تُحفظ أو تُرسل مجموعة أزرار اختيار، واختيار ما يُعرض علامات تبويب.
- الخاصية
valueهي قيمة زر الاختيار المحدَّد، وهي السلسلة الفارغة ما دام لا شيء محدَّدًا. عيِّنها لتحدّد، واستمع إلى الحدثchangeلتعرف ما حدّده الشخص. - الحدث
changeتصدره المجموعة مرة واحدة لكل تحديد، ومعه القيمة التي تحملها المجموعة سلفًا. ولا يصدر حين تعيّن أنتvalue، ولا حين يُفعَّل الخيار المحدَّد من جديد. - لا يستطيع الشخص أن يعيد مجموعة أزرار الاختيار إلى «لا شيء محدَّد». فحيث يكون عدم الجواب جوابًا حقيقيًّا، أضِف خيارًا يقول ذلك («لا شيء»، «بلا تفضيل»)، أو ابدأ وأحد الخيارات محدَّد.
- التحديد يتبع التركيز: مفتاح السهم يحدّد وهو ينتقل. فإن كان للتحديد أثر مكلف أو مرئي فورًا، فخذ الجواب من زر يؤكده، لا من الحدث
change. - القيمة التي لا يحملها أي زر اختيار تُظهر المجموعة بلا تحديد وتُحفظ: فقد يصل الخيار لاحقًا.
- القيمة
orientation="vertical"(الافتراضية) ترصّ الخيارات في عمود واحد. فضِّلها. - القيمة
orientation="horizontal"ترتّبها في صف يلتفّ. خُصَّها بخيارين قصيرين أو ثلاثة: فمتى التفّ الصف صعُب أن يُرى أيّ تسمية تتبع أيّ حلقة.
مفاتيح الأسهم واحدة في الحالين، وتسير بالترتيب المعطى، لا بحسب الموضع الذي وضع فيه الصف الملتفّ خيارًا.
الخاصيتان error و errorText تعيّنهما أنت: فالمجموعة لا تضع نفسها في حالة الخطأ أبدًا، ولا حتى حين تكون مطلوبة وبلا جواب. والمجموعة التي في حالة الخطأ ترسم نص الخطأ تحت الخيارات، وتُعرض على أنها غير صالحة، وترسم كل زر اختيار في هيئة الخطأ الخاصة به: تأخذ الحلقة والنقطة لون الخطأ، كما تأخذه صناديق مجموعة خانات الاختيار. والخيار المعطَّل لا يُظهر لون الخطأ، لأنه لا يمكن أن يكون الجواب الذي يصحّح الخطأ. وأزرار الاختيار نفسها لا تُعرض على أنها غير صالحة، فالمجموعة تقول ذلك مرة واحدة.
تغيّر القيمة لا يزيل الخطأ. أزِله حين يصير الجواب مقبولًا.
تعرض المجموعة التي للقراءة فقط إجابتها في مكانها، ليقرأها الشخص ولا يغيّرها: خطوة مراجعة، أو اختيار لا يغيّره إلا بعض الناس. يبقى Tab يدخلها عند زر الاختيار المحدَّد، وتتنقل مفاتيح الأسهم بين الخيارات من دون أن تحدّد أيًّا منها، وتُرسَل القيمة مع النموذج. ولا يرفض النموذج مجموعة مطلوبة للقراءة فقط تُركت بلا إجابة، لأن الشخص لا يستطيع الإجابة عنها. وتُرسم مثل مجموعة مفعّلة من دون استجابة التمرير والضغط.
- سمِّ المجموعة بالسؤال الذي تجيب عنه خياراتها: «التوصيل».
- أعطِ كل زر اختيار قيمة
valueلا تتكرر في المجموعة، وتسميته الخاصة. - أبقِ الخيارات قليلة. الخيار الواحد خانة اختيار، والخيارات الكثيرة عنصر اختيار.
- لا تضع في مجموعة أزرار الاختيار أي شيء آخر يمكن تشغيله: لا خانة اختيار ولا زرًّا ولا حقلًا.
- لا تعطِ أزرار الاختيار التي في المجموعة الخاصية
name. فهذه الخاصية تُتجاهل: المجموعة هي مجموعتها. - لا تضع مجموعة أزرار الاختيار في حقل أو في مجموعة حقول لتعطيها تسمية. فلها تسميتها. ويجوز أن تكون مجموعة أزرار الاختيار عضوًا واحدًا في مجموعة حقول تسمّي مجموعة أكبر («الشحن»).
- لا تجعل المجموعة للقراءة فقط بتعطيلها: المجموعة المعطّلة لا ترسل شيئًا ولا يمكن الوصول إليها. استخدم
readOnly، فهي تُبقي المجموعة في ترتيب التركيز وترسل قيمتها.
- الدور
radiogroup- التسمية
- label names the radio group, drawn or not (labelHidden). Each option keeps its own name, its own label beside it, and says its position in the set. The group's description is supportingText, then errorText while error is true, then optionalText while it is optional; a required group carries the required state, and a group in error the invalid state, so neither is said in words a second time. The requirement tag and the asterisk are hidden.
- الحد الأدنى للهدف
- تستوفي مساحة اللمس الحد الأدنى لحجم الهدف حتى لو كان الحجم المرئي أصغر. minimum 32px · pointer 44px · spacing 8px · touch 48px
لوحة المفاتيح
| المفاتيح | الإجراء |
|---|---|
| Tab / Shift+Tab | Moves focus into the group — to the selected option, or to the first enabled one while none is selected — and out of it. The group has one stop and is not a stop itself (RGP-6). |
| Down Arrow / Right Arrow | Moves to the next enabled option and selects it, wrapping from the last to the first; in a right-to-left layout Left Arrow does what Right Arrow does here (RGP-5). While the group is read-only it moves focus and selects nothing (RGP-20). |
| Up Arrow / Left Arrow | Moves to the previous enabled option and selects it, wrapping from the first to the last; in a right-to-left layout Right Arrow does what Left Arrow does here. While the group is read-only it moves focus and selects nothing. |
| Space | Selects the focused option if it is not selected (after Tab into a group with nothing selected); does nothing on the selected one. Nothing while the group is read-only. |
| Enter | Nothing on the web, where it submits the form; selects where the platform activates any focused control with Enter (Android, tvOS), as RAD-1 says. |
ملاحظات
- Not a target itself: the group takes no press and is not a focus stop (RGP-6), so minimumTarget holds through its radio buttons, each of which keeps a whole touch target of its own at the distance the group puts between them (RAD-9, RAD-21, RGP-2).
- The radio group is a field group that owns a value: its frame is the field group itself, in its radio-group kind (RGP-1, FGR-25), and it adds what a frame cannot have — one value, one change, the arrow keys and the one tab stop kept for the set, and a place in a form as one control. It has no tokens of its own. One level down is the same field group written by hand around radio buttons of one name: the same picture and the same radio group, without the value. A set of checkboxes that is one answer is a checkbox group, which holds a list of values where this holds one; a set of switches, and checkboxes that each have a name of their own, need none of that and stay a field group.
- Selection follows focus: an arrow key selects as it moves, as every platform's own radio buttons do, so the arrow keys never leave focus on an option that is not the answer. A product in which a selection has an expensive or a visible effect at once (it saves, it loads) should take the answer from a button that confirms it, not from change.
- A person cannot return a radio group to "nothing selected". Where no answer is a real answer, add an option that says so ("None", "No preference"), or let the form start with one option selected. The product can still set value to the empty string.
- A group in error is told by its error text, which is words (WCAG 3.3.1), and by the invalid state; the error color its radio buttons take (RAD-26) is one more sign and never the only one (WCAG 1.4.1), and no radio button is exposed as invalid by itself. The error text is announced when it appears under the person's focus and is otherwise read with the group's description (RGP-8, RGP-10); it never takes focus away.
- When a radio group, and when something else. One value from a few options that are all worth seeing at once, in a form or a setting: a radio group, of up to about five options. A choice that changes the content shown below it — which view, which sample, which period: tabs. One value from many options, or where there is little room: a select. Several of several: a checkbox group. On or off, taking effect at once: a switch. Buttons side by side that each toggle on their own: a button group. A segmented button exists only in a design system that ships one.
- Prefer a column. A row is for two or three short options; once it wraps, which label belongs to which ring is harder to see.
- On the web the radio group that assistive technology is told of is the field group's own element inside the component's shadow root, which carries the radiogroup role in its radio-group kind, around the slot that holds the radio buttons; the role's required and invalid states are why a set of radio buttons is not a plain group. iOS has no radio group trait: the container is an accessibility container whose label is the group's, and each option says its position through its value, as the radio button's spec notes.
- Heights are the texts' and the options': 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.
- A radio button the product disabled by itself keeps its place in the count, is passed over by the arrow keys and Tab, and stays selected while value is its value; its value is still submitted, because the value is the group's (RGP-7, RGP-9).
- Read-only (RGP-20) is a set that shows its answer in place and keeps it in the focus order, so that it is read with its form — on a review step, or where only some people may change it: the group says read-only (aria-readonly on the element with role radiogroup on the web, which WAI-ARIA allows on radiogroup and not on radio), each option says whether it is the chosen one, and the arrow keys move among them without choosing, as React Aria's isReadOnly radio group does. Where the answer needs no control at all, write it as text; where no one may reach the set, it is disabled.
مولَّد من specs/radio-group.spec.json, tokens/sys/measure.tokens.json
- مجموعة أزرار اختيار واحدة (radio group) تحتوي أزرار الاختيار التي لها، وتسمّيها الخاصية
label، سواء رُسمت أم أُخفيت بالخاصيةlabelHidden. - حالة المطلوب ما دامت
requiredمعيَّنة، وحالة عدم الصلاحية ما دامتerrorبالقيمة true، وحالة التعطيل ما دامتdisabledبالقيمة true، واتجاهها. - حالة القراءة فقط ما دامت
readOnlyصحيحة. عندها يكون كل زر اختيار للقراءة فقط: يبقى Tab ومفاتيح الأسهم تنقل التركيز، ولا يغيّر أي فعل من الشخصvalue. - وصف المجموعة هو
supportingText، ثمerrorTextما دامتerrorبالقيمة true، ثمoptionalTextما دامت المجموعة اختيارية. وليسrequiredTextجزءًا منه: فحالة المطلوب تقوله. - كل زر اختيار يقول موضعه في المجموعة وحجم المجموعة، والخيارات المعطَّلة محسوبة فيهما.
- موضع توقف واحد في ترتيب التركيز: زر الاختيار المحدَّد، أو أول زر مفعَّل. المفتاح Tab يدخل المجموعة من هناك ويغادرها؛ ومفاتيح الأسهم تنتقل داخلها، وتتخطى الخيار المعطَّل، وتلتفّ عند الطرفين. وفي تخطيط من اليمين إلى اليسار يتبادل مفتاحا السهم لليسار والسهم لليمين.
- الخاصية
disabledتعطّل كل زر اختيار. والمجموعة غير المعطَّلة لا تفعّل أبدًا زر اختيار عطّلته أنت: فهذا الزر تتخطاه مفاتيح الأسهم والمفتاح Tab، ويحتفظ بمكانه في العدّ، ويبقى محدَّدًا ما دامتvalueهي قيمته. - الخطأ الذي يظهر، أو تتغيّر كلماته، والتركيز على أحد أزرار الاختيار يُعلَن مرة واحدة، بتهذيب. ولا ينتقل التركيز أبدًا بسبب خطأ.
- وسم المطلوب أو الاختياري والنجمة مخفيّان عن التقنيات المساعدة.
- عند تكبير النص إلى 200% يلتفّ كل نص، ويصير الصف عمودًا، ولا يُقصّ شيء.
- في الألوان المفروضة (forced colors) يأخذ كل نص لون نص النظام ويكتسب وسم المطلوب أو الاختياري حدًّا.
- في تخطيط من اليمين إلى اليسار تبدأ الصفوف من اليمين، ويجري صف الخيارات من اليمين، ويحتفظ كل نص باتجاهه.
- على الويب هي عنصر تحكم واحد في نموذجها: ترسل
valueتحت الاسمname، وتعود عند إعادة الضبط إلى قيمتها الأولى، وتتبع عنصرfieldsetالمعطَّل، وتبلّغ تحقق النموذج نفسه بأن القيمة ناقصة ما دامت مطلوبة وبلا جواب. - المجموعة التي بلا زر اختيار، أو فيها عنصر تحكم آخر، أو بلا تسمية، أو فيها خياران بقيمة واحدة، أو لها قيمة لا يحملها أي خيار، يُبلَّغ عنها في بنيات التنقيح (debug).
فجوات معروفة على الويب:
- قبل أن يُعرَّف العنصر، تكون أزرار الاختيار في الصفحة بلا تسمية المجموعة ولا وصفها ولا تخطيطها ولا تحديدها.
- أعطِ المجموعة
label. - تحقق من الجواب بنفسك، وعيِّن
error، واكتبerrorTextبحيث يقول كيف يُصحَّح الجواب. - المجموعة المطلوبة التي تُركت بلا جواب يرفضها تحقق النموذج نفسه بكلمات المتصفح، كما يرفض القائمة المنسدلة. ولقول ذلك بكلمات منتجك، افعل كما يفعل GOV.UK: ضع
novalidateعلى النموذج، وعند إرساله عيِّنerrorوerrorTextعلى المجموعة. - أعطِ كلمات المطلوب والاختياري:
required-textوoptional-textعلى المجموعة، أو مرة واحدة للمنتج كله بالاستدعاءsetWords({ requiredText, optionalText }). لا يتضمن Tanrei أي كلمة: من دونrequiredTextتقف نجمة في مكان الوسم، ومن دونoptionalTextلا يُرسم وسم ولا يُقال شيء. انظر كلمات المنتج. - بعد إرسال أخفق، قل كذلك فوق النموذج ما الذي رُفض واربط بالمجموعة: تنويه حيّ في حالة الخطأ.