[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M754XGVTQ8SWNMX1GCAVHVWH":3,"skill-same:01M754XGVTQ8SWNMX1GCAVHVWH":49},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":27,"commitSha":28,"skillDirectory":29,"forksCount":30,"repositoryHtmlUrl":31,"repositoryHomepageUrl":6,"ownerHtmlUrl":32,"ownerBlogUrl":33,"ownerDescription":6,"updatedAt":34,"install":35,"resources":48},"01M754XGVTQ8SWNMX1GCAVHVWH","recursica-skill-checkbox",null,"Rules for the Recursica checkbox and checkbox group — zero-to-many selection, option counts, select-all and the indeterminate state, table row selection, and disabled versus read-only. Use for checkboxes, checklists, and row selection. Not for one choice — see recursica-skill-radio-button; not for one on\u002Foff setting that passes the switch tests — see recursica-skill-switch.","borderux\u002Frecursica-knowledge","borderux","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F14911137?v=4","01M754SG94XX2Y7176KM2WGZG3","Border LLC","01M754SGA9E7YSNK6NWVMKMHYC",1,"MIT","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fcomponents\u002Frecursica-skill-checkbox\u002FSKILL.md",[],[],"2026-11-12 13:55:43",false,"---\nname: recursica-skill-checkbox\ndescription: Rules for the Recursica checkbox and checkbox group — zero-to-many selection, option counts, select-all and the indeterminate state, table row selection, and disabled versus read-only. Use for checkboxes, checklists, and row selection. Not for one choice — see recursica-skill-radio-button; not for one on\u002Foff setting that passes the switch tests — see recursica-skill-switch.\nlicense: MIT\nmetadata:\n  author: hi@borderux.com\n  version: 0.2.0\n---\n\n# Checkbox\n\nA checkbox turns one specific value on or off, such as \"Remember me\". A checkbox group lets the persona select any number of options, from none to every option in the group.\n\n## When to use a checkbox\n\n- **Use a checkbox when the persona may select zero, one, or many options.** For example, \"How can we contact you?\" may offer Email, Phone and Text message. The options are independent. Selecting one option never rules out another option.\n- **Use a checkbox when the persona should see every option at once.** The persona should see the options in a stacked list that is easy to scan. The persona should not have to open a control, such as a dropdown, to see which options are available.\n- **Use a checkbox when the options have a parent-child relationship.** For example, a parent checkbox sums up a list of child checkboxes. An \"All regions\" checkbox above one checkbox per region is one case. The indeterminate state (the partly selected state, shown as a dash, when some but not all items are selected) exists for parent and child checkboxes.\n- **A change to a checkbox saves under the application's save mode**, like every other field in the form. In a form that saves on submit, the change saves when the persona submits the form.\n\n## When not to use a checkbox\n\n| Situation                                                                           | Use instead                                                                                                             |\n| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |\n| Selecting one option rules out the other options, and the persona picks exactly one | A radio group. See `recursica-skill-radio-button`. Never use checkboxes when the persona picks exactly one option.      |\n| There is one lone yes-or-no field, with no others beside the field                  | A switch or a checkbox. Confirm the choice with the user. See `recursica-skill-switch`.                                 |\n| A checkbox group needs well over the 7 ± 2 guideline in the rules below             | A multi-select dropdown. See `recursica-skill-dropdown`. A multi-select dropdown is a checkbox group inside a dropdown. |\n| The options must sit side by side in a horizontal row                               | Selectable chips. See `recursica-skill-chip`. Never lay out a checkbox group in a horizontal row.                       |\n| The persona chooses an action, such as \"Send invoice\", not a value                  | A button. See `recursica-skill-button`.                                                                                 |\n| The persona viewing the field can never edit the value                              | A read-only field, which shows the label and the value as text, with no input. See `recursica-skill-read-only-field`.   |\n\n**Do not use a disabled checkbox to show a value.** For example, \"Email verified\" on an account page is a value nobody can change there. A value that nobody can ever change where the value is shown does not belong in a form control.\n\n## Variants\n\n**Use only the checkbox variants and options that the knowledge MCP server lists for the theme (the design a designer sets in Theme Forge: the token values, the components, and each component's variants, states and sizes).** A designer can add variants and options in Theme Forge, so each theme can differ. Get the list with the server's `component_api` tool, and use the names the code uses. Never invent a variant or an option.\n\nEach option below is described by role, such as \"the checked state\". A name from the standard UI kit (the unchanged UI kit in the official Recursica release) is only an example.\n\n**A checkbox field has three components.** In the standard UI kit, the three components are `checkbox-group`, `checkbox-item`, and `checkbox`.\n\n- A checkbox is the box, and holds whether the box is selected.\n- A checkbox item holds the label of one option, and pairs the label with a box.\n- A checkbox group sets the layout of the checkbox items.\n\n**Use all three components together.** Never place bare `checkbox` components in a form and call the checkboxes a group.\n\n- **A checkbox has three selection states.** A checkbox is checked, unchecked, or indeterminate. In the standard UI kit, the variant is `selection-states`, with the options `checked`, `unchecked`, and `indeterminate`.\n- **The indeterminate state is a state of the checkbox, not a separate component.** A select-all checkbox or a parent checkbox shows the indeterminate state when some child checkboxes are checked, but not all.\n- **The website and the UI kit use different names for two selection states.** Only the design-system website says \"Selected\" and \"Unselected\". The standard UI kit says `checked` and `unchecked`. Both pairs of names mean the same two states.\n- **The disabled state is set on each checkbox item.** One option can then be unavailable while the options next to the disabled option stay usable. In the standard UI kit, the variant is `states`, with the option `disabled`. The checkbox components show the disabled look automatically.\n- **A disabled checkbox item still has a selection state.** Only the design-system website shows two more names, `Selected-disabled` and `Indeterminate-disabled`. Each name combines two settings: the disabled state of the checkbox item, and the selection state of the checkbox. Neither name is an extra selection state.\n\n**Label placement is a variant, the same variant every field has.** A group's label sits beside the stack of items or above the stack of items. In the standard UI kit, the variant is `layouts`, with the options `side-by-side` and `stacked`. The label placement variant belongs to the checkbox group, because label placement is one decision for the whole field.\n\n**Never read `side-by-side` as \"put the checkboxes in a row.\"** Label placement sets where the group label sits, not which way the checkbox items run. Checkbox items are always stacked vertically. `recursica-skill-selection-controls` forbids a horizontal checkbox group outright.\n\n## Rules\n\n**Put at least two checkbox items in a checkbox group.** One checkbox alone is not a group. For a single yes-or-no field, confirm with the user whether to use a switch instead.\n\n**Aim for about 7 ± 2 options in a checkbox group.** The number is a guideline from psychology, not a hard limit. Use judgment. For example, more items fit when every label is short. Going well past the guideline is a sign that a different pattern or component may fit better. `recursica-skill-working-memory` gives the reason.\n\n- Lean toward fewer options when the options differ from each other, are hard to understand, or need specialist knowledge.\n- If a checkbox group needs more options than the limit, use a multi-select dropdown instead.\n\n**A long form is a valid reason to replace a checkbox group with a multi-select dropdown**, even below the limit. Six options that are easy to read are normally checkboxes. A multi-select dropdown can still be the right choice when the dropdown saves a lot of scrolling down the page.\n\n**Stack checkbox items vertically. Never lay out checkbox items horizontally.** In a horizontal row of checkboxes, the persona cannot easily tell which box belongs to which label. If the layout needs the options in a row, use selectable chips instead of a checkbox group.\n\n**Label placement is one decision per form, not per field.** This group uses the same label placement as every other field in the form. Apply the container-width test once, to the whole form. The result sets the placement of every field in the form. Short fields that would fit side by side follow the result too. A form may change placement at a breakpoint. A form never mixes placements at one breakpoint. A form section never gets a separate placement. `recursica-skill-forms` sets this rule.\n\n**Check an option in advance only when the option passes both tests in `recursica-skill-screen-starting-state`.** About 90 percent of personas would choose the option. The option has no major effects later in the workflow. For example, never check \"Subscribe to marketing emails\" in advance.\n\n**Put a selection rule in assistive text, not in a validation message.** The persona sees a validation message only after breaking the rule. For example, put \"At least two options required\" under the group. Show the assistive text with the assistive element. See `recursica-skill-assistive-element`.\n\n**A select-all checkbox is allowed, and the select-all checkbox uses the indeterminate state.** When the persona selects all, then deselects one checkbox item, the select-all control changes to the indeterminate state.\n\n**Treat a need for select all as a warning sign.** A checkbox group is the wrong control if checking checkbox items one at a time would tire the persona. A group of twenty checkboxes is one example. Fix the screen's structure before adding the select-all affordance (a visible cue that a control can be used, such as the underline on a link).\n\n**To select table rows, add a checkbox to each table row and to the table header.** Put each row's checkbox in the leftmost cell of the table row. The header checkbox always follows three rules:\n\n- A click on an indeterminate header checkbox **always makes the header checkbox fully checked.** The click never makes the header checkbox unchecked.\n- A click on a fully checked header checkbox makes the header checkbox fully unchecked. A click on a fully unchecked header checkbox makes the header checkbox fully checked.\n- The header checkbox becomes indeterminate **only** when the persona selects or deselects individual table rows. A click on the header checkbox never makes the header checkbox indeterminate.\n\n**A checkbox may reveal more fields, and the whole form still submits together.** For example, checking \"Car\" may reveal a group of car details directly below the checkbox. Keep the revealed content right next to the checkbox that revealed the content.\n\n**Never mix instant saving with saving the whole form together.** A checkbox group in a form that submits with a button must not save when the selection changes. For example, in a form with a Save button, checking \"Email\" saves nothing until the persona clicks Save.\n\n**A disabled checkbox item and a read-only field are different components, not two styles of one component.**\n\n- **Use a disabled checkbox item when the persona could make the item usable by first taking a different action.** A disabled item is still a checkbox and still clearly a control. The persona cannot use the disabled item right now.\n- **Use a read-only field when the persona viewing the field never changes the value where the value is shown.** A read-only field, `read-only-field` in the standard UI kit, is a different component. A read-only field shows text, with no input at all.\n\n## Accessibility\n\nThe rules below add to the accessibility baseline in `recursica-skill-design-system-conventions`, which every Recursica component follows.\n\nThe checkbox component pairs each box with the item label, and provides the focus ring. Each app must:\n\n- give the group a name\n- make each checkbox's state available in code\n- add the behavior in the two lists below\n\nApps most often miss the behavior in the two lists.\n\n### Screen readers\n\n- **Set a real label on every checkbox item (`checkbox-item`).** The item label is the accessible name (the name a screen reader reads out for a control). Text placed beside a box is not a label, and leaves the checkbox with no accessible name.\n- **Set a separate label on the checkbox group (`checkbox-group`).** A screen reader must announce the group label when focus enters the group. A group label that only sits above the group in the reading order is not enough. Without the group label, the persona hears a list of options with no question.\n- **The group label and the item labels do different jobs.** For example, the group label asks \"How can we contact you?\", and each item label names one answer, such as \"Email\". Never use the group label to do an item label's job. Never use an item label to do the group label's job. See `recursica-skill-label`.\n- **Make the checked state available in code.** Never show the checked state only by a fill color or a check mark. A persona who cannot see the box must still hear \"checked\" or \"not checked\". The rule comes from `recursica-skill-design-system-conventions`.\n- **Make the indeterminate state available in code as a mixed state**, not as a dash that exists only on screen. A persona using a screen reader hears \"partially checked\" from a mixed state, and hears nothing from a dash.\n- **A select-all control must name what the control selects**, as in \"Select all rows\". Never use a bare \"Select all\" in a table header.\n- **In a table, each row checkbox must name the table row.** Name the table row in one of two ways:\n\n  - Put the name of the table row's item in the checkbox's accessible name.\n  - Let the table row supply the item's name in code.\n\n  Thirteen announcements of \"checkbox, unchecked\" tell the persona nothing.\n\n- **When a checkbox reveals more fields, tell the persona before the persona checks the box.** Say that more fields will appear, in the item label or in the group's assistive text. Fields that appear below without an announcement are easy to miss when the page is read in order.\n\n### Keyboard and non-mouse navigation\n\n- **Space toggles a checkbox.** Personas expect the Space key. Do not remap Space, do not require Enter instead, and do not block Space.\n- **The adapter (the Recursica component library for one framework, such as Mantine or Angular Material) handles the keys inside the checkbox.** Do not add custom key handlers to the box, and do not rebuild the toggling. A custom key handler or rebuilt toggling breaks behavior that works.\n- **Every checkbox in a group is a separate tab stop** (a place the Tab key lands). A radio group works the opposite way, with one tab stop for the whole group. Do not add roving focus (where the arrow keys move between items that share one tab stop) inside a checkbox group. Do not repurpose Home and End. Home and End belong to the page.\n- **Clicking or tapping the item label toggles the checkbox.** A real label connected to the box toggles the checkbox automatically, and gives the persona a bigger target. Do not show the label as text that is not connected to the box.\n- **Do not move focus for the persona.** When a checkbox reveals fields below, focus stays on the checkbox. The persona reaches the new fields with the next Tab. Moving focus into the revealed fields takes a persona using a keyboard or a screen reader away from the checkbox.\n\n## Styling set by tokens\n\n**Never set or override the checkbox's styling.** The theme sets every visual property of the checkbox, such as size, spacing, borders, colors and animation. Do not add extra containers or spacers to change the checkbox's look. If the theme does not give a look the design needs, report the missing look as a design-system gap. See `recursica-skill-design-router`.\n\n**Do not add margins or spacer elements in the following places:**\n\n- between checkbox items\n- between the group label and the checkbox items\n- between the checkbox group and the elements next to the group\n\n## Related skills\n\n- `recursica-skill-selection-controls` — the selection-control rules:\n  - which control a field gets: a checkbox, a switch, or a radio button\n  - option counts\n  - pre-selection\n  - select all\n  - how table row selection works\n  - vertical layout only\n  - when a change saves\n- `recursica-skill-forms` — the form rules:\n  - single-column layout\n  - label placement, and the container width that decides label placement\n  - one label placement per form\n  - marking a field required or optional\n  - when validation runs\n  - save mode\n  - the rule that no form control goes inside a card\n- `recursica-skill-label` — the label rules:\n  - the group label and the item labels\n  - label text that makes sense without the text around the label\n  - the required and optional markers\n- `recursica-skill-assistive-element` — the help text and error text below the group, and the wording rules for both.\n- `recursica-skill-working-memory` — the reason for the 7 ± 2 guideline. The skill also sets the line between recognizing an option and comparing options. The line decides when a long list is acceptable.\n- `recursica-skill-tables` — the table structure around row selection and the header checkbox.\n- `recursica-skill-design-system-conventions` — two design system conventions:\n  - never showing a meaning in only one way\n  - fixing the screen's structure instead of adding a mechanism, such as select all, to cope with a bad structure\n\n## Open questions\n\n- **How a checkbox group shows an error.** A checkbox group can have a selection rule that fails validation. No rule says how a checkbox group shows the validation error. If the theme has an error state for any of the three checkbox components, use that error state. Otherwise, confirm with the user.\n- **Whether the theme has a multi-select dropdown.** `recursica-skill-selection-controls` requires a multi-select dropdown in two places. If the theme has a multi-select dropdown, use that multi-select dropdown. Otherwise, follow the steps under \"Missing components\" in `recursica-skill-design-router`.\n  - A theme with no multi-select dropdown has a gap in the list of components. The gap is not permission to build a multi-select dropdown from other parts.\n  - Do not put a checkbox group inside a dropdown.\n  - Confirm with the user before using a transfer list instead.\n  - When the persona must filter by several values, one build test used separate single-value filters that AND together (a row appears only if the row matches every filter). The workaround succeeded.\n- **Whether a select-all control is a `checkbox-item` in the group, or a separate control outside the group.**\n- **Limits on selection.** No rule says whether a persona may be limited to selecting _n_ options out of many.\n- **How deep parent-child checkboxes may nest.** The indeterminate state implies a hierarchy of parent and child checkboxes. No rule says how many levels deep the hierarchy may go. No rule says how a parent checkbox's state is worked out beyond one level.\n\n## Pre-flight checklist\n\n- [ ] Selecting one option never rules out another option, and no single-choice question is built as checkboxes.\n- [ ] The group holds at least two items, and about 7 ± 2 or fewer. Label length and how alike the options are guide the count.\n- [ ] Checkbox items are stacked vertically. There is no horizontal group, and `side-by-side` is used only for label placement.\n- [ ] Label placement matches every other field in the same form. Each form has one placement at each breakpoint, with no mixing between fields or form sections.\n- [ ] `checkbox`, `checkbox-item`, and `checkbox-group` are used together. No form holds a bare `checkbox` without the item and the group.\n- [ ] The group has a real label, and every item has a real label. The group label never does an item label's job, and an item label never does the group label's job.\n- [ ] The group label is announced when focus enters the group.\n- [ ] The checked and indeterminate states are available in code, never shown only by a fill or a mark.\n- [ ] Selection rules are in assistive text shown with the assistive element, and the required state is available in code.\n- [ ] A select-all control appears only where the group is long, and clicking an indeterminate header checkbox selects all.\n- [ ] Each row checkbox in a table names the table row, and the header checkbox names what the header checkbox selects.\n- [ ] Space toggles the box, and every checkbox is a separate tab stop.\n- [ ] The arrow keys do not move focus between items, and key handling comes from the adapter.\n- [ ] Clicking the item label toggles the box.\n- [ ] Focus is never moved for the persona, including when a checkbox reveals fields below.\n- [ ] The disabled state is used only for options that are unavailable for now. A value that can never be edited uses the read-only field.\n- [ ] Every variant, size, and state is one the knowledge MCP server lists for the theme.\n- [ ] No styling is set or overridden on the checkbox.\n- [ ] No container or spacer is added to change the checkbox's look.\n- [ ] The group saves with the form, in the same save mode as every other part of the application.\n- [ ] Open questions were asked about, not decided: the group error state, the multi-select dropdown, where a select-all control sits, limits on selection, and nesting depth.\n","# Checkbox\n\nA checkbox turns one specific value on or off, such as \"Remember me\". A checkbox group lets the persona select any number of options, from none to every option in the group.\n\n## When to use a checkbox\n\n- **Use a checkbox when the persona may select zero, one, or many options.** For example, \"How can we contact you?\" may offer Email, Phone and Text message. The options are independent. Selecting one option never rules out another option.\n- **Use a checkbox when the persona should see every option at once.** The persona should see the options in a stacked list that is easy to scan. The persona should not have to open a control, such as a dropdown, to see which options are available.\n- **Use a checkbox when the options have a parent-child relationship.** For example, a parent checkbox sums up a list of child checkboxes. An \"All regions\" checkbox above one checkbox per region is one case. The indeterminate state (the partly selected state, shown as a dash, when some but not all items are selected) exists for parent and child checkboxes.\n- **A change to a checkbox saves under the application's save mode**, like every other field in the form. In a form that saves on submit, the change saves when the persona submits the form.\n\n## When not to use a checkbox\n\n| Situation                                                                           | Use instead                                                                                                             |\n| ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |\n| Selecting one option rules out the other options, and the persona picks exactly one | A radio group. See `recursica-skill-radio-button`. Never use checkboxes when the persona picks exactly one option.      |\n| There is one lone yes-or-no field, with no others beside the field                  | A switch or a checkbox. Confirm the choice with the user. See `recursica-skill-switch`.                                 |\n| A checkbox group needs well over the 7 ± 2 guideline in the rules below             | A multi-select dropdown. See `recursica-skill-dropdown`. A multi-select dropdown is a checkbox group inside a dropdown. |\n| The options must sit side by side in a horizontal row                               | Selectable chips. See `recursica-skill-chip`. Never lay out a checkbox group in a horizontal row.                       |\n| The persona chooses an action, such as \"Send invoice\", not a value                  | A button. See `recursica-skill-button`.                                                                                 |\n| The persona viewing the field can never edit the value                              | A read-only field, which shows the label and the value as text, with no input. See `recursica-skill-read-only-field`.   |\n\n**Do not use a disabled checkbox to show a value.** For example, \"Email verified\" on an account page is a value nobody can change there. A value that nobody can ever change where the value is shown does not belong in a form control.\n\n## Variants\n\n**Use only the checkbox variants and options that the knowledge MCP server lists for the theme (the design a designer sets in Theme Forge: the token values, the components, and each component's variants, states and sizes).** A designer can add variants and options in Theme Forge, so each theme can differ. Get the list with the server's `component_api` tool, and use the names the code uses. Never invent a variant or an option.\n\nEach option below is described by role, such as \"the checked state\". A name from the standard UI kit (the unchanged UI kit in the official Recursica release) is only an example.\n\n**A checkbox field has three components.** In the standard UI kit, the three components are `checkbox-group`, `checkbox-item`, and `checkbox`.\n\n- A checkbox is the box, and holds whether the box is selected.\n- A checkbox item holds the label of one option, and pairs the label with a box.\n- A checkbox group sets the layout of the checkbox items.\n\n**Use all three components together.** Never place bare `checkbox` components in a form and call the checkboxes a group.\n\n- **A checkbox has three selection states.** A checkbox is checked, unchecked, or indeterminate. In the standard UI kit, the variant is `selection-states`, with the options `checked`, `unchecked`, and `indeterminate`.\n- **The indeterminate state is a state of the checkbox, not a separate component.** A select-all checkbox or a parent checkbox shows the indeterminate state when some child checkboxes are checked, but not all.\n- **The website and the UI kit use different names for two selection states.** Only the design-system website says \"Selected\" and \"Unselected\". The standard UI kit says `checked` and `unchecked`. Both pairs of names mean the same two states.\n- **The disabled state is set on each checkbox item.** One option can then be unavailable while the options next to the disabled option stay usable. In the standard UI kit, the variant is `states`, with the option `disabled`. The checkbox components show the disabled look automatically.\n- **A disabled checkbox item still has a selection state.** Only the design-system website shows two more names, `Selected-disabled` and `Indeterminate-disabled`. Each name combines two settings: the disabled state of the checkbox item, and the selection state of the checkbox. Neither name is an extra selection state.\n\n**Label placement is a variant, the same variant every field has.** A group's label sits beside the stack of items or above the stack of items. In the standard UI kit, the variant is `layouts`, with the options `side-by-side` and `stacked`. The label placement variant belongs to the checkbox group, because label placement is one decision for the whole field.\n\n**Never read `side-by-side` as \"put the checkboxes in a row.\"** Label placement sets where the group label sits, not which way the checkbox items run. Checkbox items are always stacked vertically. `recursica-skill-selection-controls` forbids a horizontal checkbox group outright.\n\n## Rules\n\n**Put at least two checkbox items in a checkbox group.** One checkbox alone is not a group. For a single yes-or-no field, confirm with the user whether to use a switch instead.\n\n**Aim for about 7 ± 2 options in a checkbox group.** The number is a guideline from psychology, not a hard limit. Use judgment. For example, more items fit when every label is short. Going well past the guideline is a sign that a different pattern or component may fit better. `recursica-skill-working-memory` gives the reason.\n\n- Lean toward fewer options when the options differ from each other, are hard to understand, or need specialist knowledge.\n- If a checkbox group needs more options than the limit, use a multi-select dropdown instead.\n\n**A long form is a valid reason to replace a checkbox group with a multi-select dropdown**, even below the limit. Six options that are easy to read are normally checkboxes. A multi-select dropdown can still be the right choice when the dropdown saves a lot of scrolling down the page.\n\n**Stack checkbox items vertically. Never lay out checkbox items horizontally.** In a horizontal row of checkboxes, the persona cannot easily tell which box belongs to which label. If the layout needs the options in a row, use selectable chips instead of a checkbox group.\n\n**Label placement is one decision per form, not per field.** This group uses the same label placement as every other field in the form. Apply the container-width test once, to the whole form. The result sets the placement of every field in the form. Short fields that would fit side by side follow the result too. A form may change placement at a breakpoint. A form never mixes placements at one breakpoint. A form section never gets a separate placement. `recursica-skill-forms` sets this rule.\n\n**Check an option in advance only when the option passes both tests in `recursica-skill-screen-starting-state`.** About 90 percent of personas would choose the option. The option has no major effects later in the workflow. For example, never check \"Subscribe to marketing emails\" in advance.\n\n**Put a selection rule in assistive text, not in a validation message.** The persona sees a validation message only after breaking the rule. For example, put \"At least two options required\" under the group. Show the assistive text with the assistive element. See `recursica-skill-assistive-element`.\n\n**A select-all checkbox is allowed, and the select-all checkbox uses the indeterminate state.** When the persona selects all, then deselects one checkbox item, the select-all control changes to the indeterminate state.\n\n**Treat a need for select all as a warning sign.** A checkbox group is the wrong control if checking checkbox items one at a time would tire the persona. A group of twenty checkboxes is one example. Fix the screen's structure before adding the select-all affordance (a visible cue that a control can be used, such as the underline on a link).\n\n**To select table rows, add a checkbox to each table row and to the table header.** Put each row's checkbox in the leftmost cell of the table row. The header checkbox always follows three rules:\n\n- A click on an indeterminate header checkbox **always makes the header checkbox fully checked.** The click never makes the header checkbox unchecked.\n- A click on a fully checked header checkbox makes the header checkbox fully unchecked. A click on a fully unchecked header checkbox makes the header checkbox fully checked.\n- The header checkbox becomes indeterminate **only** when the persona selects or deselects individual table rows. A click on the header checkbox never makes the header checkbox indeterminate.\n\n**A checkbox may reveal more fields, and the whole form still submits together.** For example, checking \"Car\" may reveal a group of car details directly below the checkbox. Keep the revealed content right next to the checkbox that revealed the content.\n\n**Never mix instant saving with saving the whole form together.** A checkbox group in a form that submits with a button must not save when the selection changes. For example, in a form with a Save button, checking \"Email\" saves nothing until the persona clicks Save.\n\n**A disabled checkbox item and a read-only field are different components, not two styles of one component.**\n\n- **Use a disabled checkbox item when the persona could make the item usable by first taking a different action.** A disabled item is still a checkbox and still clearly a control. The persona cannot use the disabled item right now.\n- **Use a read-only field when the persona viewing the field never changes the value where the value is shown.** A read-only field, `read-only-field` in the standard UI kit, is a different component. A read-only field shows text, with no input at all.\n\n## Accessibility\n\nThe rules below add to the accessibility baseline in `recursica-skill-design-system-conventions`, which every Recursica component follows.\n\nThe checkbox component pairs each box with the item label, and provides the focus ring. Each app must:\n\n- give the group a name\n- make each checkbox's state available in code\n- add the behavior in the two lists below\n\nApps most often miss the behavior in the two lists.\n\n### Screen readers\n\n- **Set a real label on every checkbox item (`checkbox-item`).** The item label is the accessible name (the name a screen reader reads out for a control). Text placed beside a box is not a label, and leaves the checkbox with no accessible name.\n- **Set a separate label on the checkbox group (`checkbox-group`).** A screen reader must announce the group label when focus enters the group. A group label that only sits above the group in the reading order is not enough. Without the group label, the persona hears a list of options with no question.\n- **The group label and the item labels do different jobs.** For example, the group label asks \"How can we contact you?\", and each item label names one answer, such as \"Email\". Never use the group label to do an item label's job. Never use an item label to do the group label's job. See `recursica-skill-label`.\n- **Make the checked state available in code.** Never show the checked state only by a fill color or a check mark. A persona who cannot see the box must still hear \"checked\" or \"not checked\". The rule comes from `recursica-skill-design-system-conventions`.\n- **Make the indeterminate state available in code as a mixed state**, not as a dash that exists only on screen. A persona using a screen reader hears \"partially checked\" from a mixed state, and hears nothing from a dash.\n- **A select-all control must name what the control selects**, as in \"Select all rows\". Never use a bare \"Select all\" in a table header.\n- **In a table, each row checkbox must name the table row.** Name the table row in one of two ways:\n\n  - Put the name of the table row's item in the checkbox's accessible name.\n  - Let the table row supply the item's name in code.\n\n  Thirteen announcements of \"checkbox, unchecked\" tell the persona nothing.\n\n- **When a checkbox reveals more fields, tell the persona before the persona checks the box.** Say that more fields will appear, in the item label or in the group's assistive text. Fields that appear below without an announcement are easy to miss when the page is read in order.\n\n### Keyboard and non-mouse navigation\n\n- **Space toggles a checkbox.** Personas expect the Space key. Do not remap Space, do not require Enter instead, and do not block Space.\n- **The adapter (the Recursica component library for one framework, such as Mantine or Angular Material) handles the keys inside the checkbox.** Do not add custom key handlers to the box, and do not rebuild the toggling. A custom key handler or rebuilt toggling breaks behavior that works.\n- **Every checkbox in a group is a separate tab stop** (a place the Tab key lands). A radio group works the opposite way, with one tab stop for the whole group. Do not add roving focus (where the arrow keys move between items that share one tab stop) inside a checkbox group. Do not repurpose Home and End. Home and End belong to the page.\n- **Clicking or tapping the item label toggles the checkbox.** A real label connected to the box toggles the checkbox automatically, and gives the persona a bigger target. Do not show the label as text that is not connected to the box.\n- **Do not move focus for the persona.** When a checkbox reveals fields below, focus stays on the checkbox. The persona reaches the new fields with the next Tab. Moving focus into the revealed fields takes a persona using a keyboard or a screen reader away from the checkbox.\n\n## Styling set by tokens\n\n**Never set or override the checkbox's styling.** The theme sets every visual property of the checkbox, such as size, spacing, borders, colors and animation. Do not add extra containers or spacers to change the checkbox's look. If the theme does not give a look the design needs, report the missing look as a design-system gap. See `recursica-skill-design-router`.\n\n**Do not add margins or spacer elements in the following places:**\n\n- between checkbox items\n- between the group label and the checkbox items\n- between the checkbox group and the elements next to the group\n\n## Related skills\n\n- `recursica-skill-selection-controls` — the selection-control rules:\n  - which control a field gets: a checkbox, a switch, or a radio button\n  - option counts\n  - pre-selection\n  - select all\n  - how table row selection works\n  - vertical layout only\n  - when a change saves\n- `recursica-skill-forms` — the form rules:\n  - single-column layout\n  - label placement, and the container width that decides label placement\n  - one label placement per form\n  - marking a field required or optional\n  - when validation runs\n  - save mode\n  - the rule that no form control goes inside a card\n- `recursica-skill-label` — the label rules:\n  - the group label and the item labels\n  - label text that makes sense without the text around the label\n  - the required and optional markers\n- `recursica-skill-assistive-element` — the help text and error text below the group, and the wording rules for both.\n- `recursica-skill-working-memory` — the reason for the 7 ± 2 guideline. The skill also sets the line between recognizing an option and comparing options. The line decides when a long list is acceptable.\n- `recursica-skill-tables` — the table structure around row selection and the header checkbox.\n- `recursica-skill-design-system-conventions` — two design system conventions:\n  - never showing a meaning in only one way\n  - fixing the screen's structure instead of adding a mechanism, such as select all, to cope with a bad structure\n\n## Open questions\n\n- **How a checkbox group shows an error.** A checkbox group can have a selection rule that fails validation. No rule says how a checkbox group shows the validation error. If the theme has an error state for any of the three checkbox components, use that error state. Otherwise, confirm with the user.\n- **Whether the theme has a multi-select dropdown.** `recursica-skill-selection-controls` requires a multi-select dropdown in two places. If the theme has a multi-select dropdown, use that multi-select dropdown. Otherwise, follow the steps under \"Missing components\" in `recursica-skill-design-router`.\n  - A theme with no multi-select dropdown has a gap in the list of components. The gap is not permission to build a multi-select dropdown from other parts.\n  - Do not put a checkbox group inside a dropdown.\n  - Confirm with the user before using a transfer list instead.\n  - When the persona must filter by several values, one build test used separate single-value filters that AND together (a row appears only if the row matches every filter). The workaround succeeded.\n- **Whether a select-all control is a `checkbox-item` in the group, or a separate control outside the group.**\n- **Limits on selection.** No rule says whether a persona may be limited to selecting _n_ options out of many.\n- **How deep parent-child checkboxes may nest.** The indeterminate state implies a hierarchy of parent and child checkboxes. No rule says how many levels deep the hierarchy may go. No rule says how a parent checkbox's state is worked out beyond one level.\n\n## Pre-flight checklist\n\n- [ ] Selecting one option never rules out another option, and no single-choice question is built as checkboxes.\n- [ ] The group holds at least two items, and about 7 ± 2 or fewer. Label length and how alike the options are guide the count.\n- [ ] Checkbox items are stacked vertically. There is no horizontal group, and `side-by-side` is used only for label placement.\n- [ ] Label placement matches every other field in the same form. Each form has one placement at each breakpoint, with no mixing between fields or form sections.\n- [ ] `checkbox`, `checkbox-item`, and `checkbox-group` are used together. No form holds a bare `checkbox` without the item and the group.\n- [ ] The group has a real label, and every item has a real label. The group label never does an item label's job, and an item label never does the group label's job.\n- [ ] The group label is announced when focus enters the group.\n- [ ] The checked and indeterminate states are available in code, never shown only by a fill or a mark.\n- [ ] Selection rules are in assistive text shown with the assistive element, and the required state is available in code.\n- [ ] A select-all control appears only where the group is long, and clicking an indeterminate header checkbox selects all.\n- [ ] Each row checkbox in a table names the table row, and the header checkbox names what the header checkbox selects.\n- [ ] Space toggles the box, and every checkbox is a separate tab stop.\n- [ ] The arrow keys do not move focus between items, and key handling comes from the adapter.\n- [ ] Clicking the item label toggles the box.\n- [ ] Focus is never moved for the persona, including when a checkbox reveals fields below.\n- [ ] The disabled state is used only for options that are unavailable for now. A value that can never be edited uses the read-only field.\n- [ ] Every variant, size, and state is one the knowledge MCP server lists for the theme.\n- [ ] No styling is set or overridden on the checkbox.\n- [ ] No container or spacer is added to change the checkbox's look.\n- [ ] The group saves with the form, in the same save mode as every other part of the application.\n- [ ] Open questions were asked about, not decided: the group error state, the multi-select dropdown, where a select-all control sits, limits on selection, and nesting depth.\n",{"name":5,"license":15,"metadata":24,"description":7},{"author":25,"version":26},"hi@borderux.com","0.2.0","main","110b382bfe525d171ba33c7074d6ad1f3762548f","skills\u002Fcomponents\u002Frecursica-skill-checkbox",0,"https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge","https:\u002F\u002Fgithub.com\u002Fborderux","https:\u002F\u002Fborderux.com","2026-11-09 16:39:27",{"source":8,"skillName":5,"commands":36,"prompt":46,"zipAvailable":47},[37,40,43],{"tool":38,"command":39},"npx","npx skills add borderux\u002Frecursica-knowledge --skill recursica-skill-checkbox",{"tool":41,"command":42},"bunx","bunx skills add borderux\u002Frecursica-knowledge --skill recursica-skill-checkbox",{"tool":44,"command":45},"pnpm","pnpm dlx skills add borderux\u002Frecursica-knowledge --skill recursica-skill-checkbox","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fcomponents\u002Frecursica-skill-checkbox\u002FSKILL.md",true,[],[50,58,65,72,79,86],{"skillNo":51,"name":52,"nameZh":6,"description":53,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":54,"sourceHtmlUrl":55,"categories":56,"keywords":57,"publishedAt":19},"01M7556E67F3DCE39P7ZTVT5TA","recursica-skill-template","Replace with a description of the skill and its purpose.","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Ftemplate\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Ftemplate\u002FSKILL.md",[],[],{"skillNo":59,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":64,"publishedAt":19},"01M75569FCJXWWGXRVMTJFBK0W","recursica-skill-working-memory","The research behind Recursica's item-count limits, with citations — Miller's 7 ± 2, Cowan's 4, chunking, and recognition versus recall. Use when a decision turns on how many options, navigation items, or chips to show at once, or to justify or challenge a count. Not for choosing a control — see recursica-skill-selection-controls.","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fpsychology\u002Frecursica-skill-working-memory\u002FSKILL.md",[],[],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":19},"01M75564EC5E5QKBPNWARQVDBC","recursica-skill-discoverability","The research behind Recursica's rule that rarely needed settings get a real but unpromoted entry point — the paradox of the active user, satisficing (settling for the first method that is good enough), and progressive disclosure, with citations. Use when deciding whether to hide, promote, or build a configuration or customization feature, or to justify that choice. Not for item counts — see recursica-skill-working-memory.","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fpsychology\u002Frecursica-skill-discoverability\u002FSKILL.md",[],[],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":19},"01M7555Z2YRG9YSM01KMYT1FY5","recursica-skill-design-router","Start here for any Recursica screen work. The router says what to decide in what order, which skill owns each decision, which rule wins when two rules conflict, and when to confirm with the user instead of guessing. Load the router first to design, build, review, or refactor a screen, page, panel, or flow, or when rules seem to disagree or no rule applies. The router routes, and the owning skill holds the rules.","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fmeta\u002Frecursica-skill-design-router\u002FSKILL.md",[],[],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":83,"categories":84,"keywords":85,"publishedAt":19},"01M7555RYHBH6XM48V2420Z66X","recursica-skill-undo","House rules for undo — when an action gets an undo instead of a confirmation, where the undo goes (on the page, in place, or in a toast), when a toast is needed at all, and the Undo button's accessible name. Use whenever an action can be reversed, or when choosing between an undo and a confirmation. Not for building the toast that holds an Undo button — see recursica-skill-toast. Not for the confirmation modal — see recursica-skill-buttons-links.","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fdesign-rules\u002Frecursica-skill-undo\u002FSKILL.md",[],[],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":90,"categories":91,"keywords":92,"publishedAt":19},"01M7555K4E6TKJ9E9P7GCQYJZ8","recursica-skill-typography-semantics","House rules for type and semantic markup — real elements instead of styled divs, one H1 per page, type styles from tokens only, loading the brand typefaces, hidden headings, emphasis with em and strong, abbreviations, and AP style. Use for headings, body copy, emphasis, and the markup under a visual hierarchy. Not for naming — see recursica-skill-names-and-terms.","https:\u002F\u002Fgithub.com\u002Fborderux\u002Frecursica-knowledge\u002Fblob\u002Fmain\u002Fskills\u002Fdesign-rules\u002Frecursica-skill-typography-semantics\u002FSKILL.md",[],[]]