{"id":22878452,"url":"https://github.com/palmerhq/radio-group","last_synced_at":"2025-09-13T22:11:30.508Z","repository":{"id":34304219,"uuid":"175889391","full_name":"palmerhq/radio-group","owner":"palmerhq","description":"845 byte WAI-ARIA 1.1 compliant radio group React component","archived":false,"fork":false,"pushed_at":"2023-01-07T03:51:02.000Z","size":2282,"stargazers_count":134,"open_issues_count":30,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-07T00:06:26.742Z","etag":null,"topics":["a11y","formik","forms","radio-buttons","react","react-dom","wai-aria"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/embed/qxxnwzvy0w","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/palmerhq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-15T20:51:05.000Z","updated_at":"2025-01-16T20:47:51.000Z","dependencies_parsed_at":"2023-01-15T06:15:46.059Z","dependency_job_id":null,"html_url":"https://github.com/palmerhq/radio-group","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/palmerhq/radio-group","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmerhq%2Fradio-group","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmerhq%2Fradio-group/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmerhq%2Fradio-group/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmerhq%2Fradio-group/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/palmerhq","download_url":"https://codeload.github.com/palmerhq/radio-group/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/palmerhq%2Fradio-group/sbom","scorecard":{"id":718483,"data":{"date":"2025-08-11","repo":{"name":"github.com/palmerhq/radio-group","commit":"fe79ea64a5cf8e213f0e48f8baa6b356cc5ca17d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":1,"reason":"Found 4/29 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Warn: no topLevel permission defined: .github/workflows/size.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/palmerhq/radio-group/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/palmerhq/radio-group/main.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/palmerhq/radio-group/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/size.yml:9: update your workflow using https://app.stepsecurity.io/secureworkflow/palmerhq/radio-group/size.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/size.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/palmerhq/radio-group/size.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"79 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-257v-vj4p-3w2h","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-7r28-3m3f-r2pr","Warn: Project is vulnerable to: GHSA-r8j5-h5cx-65gg","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-92xj-mqp7-vmcj","Warn: Project is vulnerable to: GHSA-wxgw-qj99-44c2","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-phwq-j96m-2c2q","Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-qrpm-p2h7-hrv2","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-44c6-4v22-4mhx","Warn: Project is vulnerable to: GHSA-4x5v-gmq8-25ch","Warn: Project is vulnerable to: GHSA-4rq4-32rv-6wp6","Warn: Project is vulnerable to: GHSA-64g7-mvw6-v9qj","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T10:28:49.907Z","repository_id":34304219,"created_at":"2025-08-22T10:28:49.907Z","updated_at":"2025-08-22T10:28:49.907Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275033795,"owners_count":25393929,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-13T02:00:10.085Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a11y","formik","forms","radio-buttons","react","react-dom","wai-aria"],"created_at":"2024-12-13T16:29:10.959Z","updated_at":"2025-09-13T22:11:30.479Z","avatar_url":"https://github.com/palmerhq.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `@palmerhq/radio-group`\n\nAn accessible [WAI-ARIA 1.1-compliant Radio Group](https://www.w3.org/TR/wai-aria-practices-1.1/#radiobutton) React component.\n\n\u003cimg align=\"center\" src=\"./.assets/demo.gif\" width=\"400px\" alt=\"Radio group demo\" style=\"border: 1px solid #eee\" /\u003e\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [`@palmerhq/radio-group`](#palmerhqradio-group)\n  - [Installation](#installation)\n  - [Usage](#usage)\n    - [Usage with Formik v2](#usage-with-formik-v2)\n  - [API Reference](#api-reference)\n    - [`\u003cRadioGroup /\u003e`](#radiogroup-)\n      - [`labelledBy?: string`](#labelledby-string)\n      - [`onChange: (value: any) =\u003e void`](#onchange-value-any--void)\n      - [`children: React.ComponentType\u003cRadioProps\u003e[]`](#children-reactcomponenttyperadioprops)\n      - [`value: any`](#value-any)\n      - [`as?: React.ComponentType`](#as-reactcomponenttype)\n      - [`autoFocus?: boolean`](#autofocus-boolean)\n    - [`\u003cRadio\u003e`](#radio)\n      - [`value: any`](#value-any-1)\n      - [`onFocus?: () =\u003e void`](#onfocus---void)\n      - [`onBlur?: () =\u003e void`](#onblur---void)\n      - [`as?: React.ComponentType`](#as-reactcomponenttype-1)\n    - [Underlying DOM Structure](#underlying-dom-structure)\n    - [Overriding Styles](#overriding-styles)\n  - [Accessibility Features](#accessibility-features)\n  - [Authors](#authors)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Installation\n\n```\nyarn add @palmerhq/radio-group\n```\n\nOr try it out in your browser on [CodeSandbox](https://codesandbox.io/embed/qxxnwzvy0w)\n\n\u003e Note: This package uses `Array.prototype.findIndex`, so be sure that you have properly polyfilled.\n\n## Usage\n\n```tsx\nimport * as React from 'react';\nimport { RadioGroup, Radio } from '@palmerhq/radio-group';\nimport '@palmerhq/radio-group/styles.css'; // use the default styles\n\nfunction App() {\n  const [value, setValue] = React.useState\u003cstring | undefined\u003e();\n\n  return (\n    \u003c\u003e\n      \u003ch3 id=\"color\"\u003eColor\u003c/h3\u003e\n      \u003cRadioGroup\n        labelledBy=\"color\"\n        value={value}\n        onChange={value =\u003e setValue(value)}\n      \u003e\n        \u003cRadio value=\"blue\"\u003eBlue\u003c/Radio\u003e\n        \u003cRadio value=\"red\"\u003eRed\u003c/Radio\u003e\n        \u003cRadio value=\"green\"\u003eGreen\u003c/Radio\u003e\n      \u003c/RadioGroup\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Usage with Formik v2\n\n```tsx\nimport * as React from 'react';\nimport { Formik, Form, useField } from 'formik';\nimport { RadioGroup, Radio } from '@palmerhq/radio-group';\nimport '@palmerhq/radio-group/styles.css'; // use the default styles\n\nfunction FRadioGroup(props) {\n  const [{ onChange, onBlur, ...field }] = useField(props.name);\n  return (\n    \u003cRadioGroup\n      {...props}\n      {...field}\n      labelledBy={props.name}\n      onBlur={onBlur(props.name)}\n      onChange={onChange(props.name)}\n    /\u003e\n  );\n}\n\nfunction App() {\n  return (\n    \u003cFormik\n      initialValues={{ color: '' }}\n      validationSchema={Yup.object().shape({\n        color: Yup.string().required(),\n      })}\n      onSubmit={(values, { setSubmitting }) =\u003e {\n        setTimeout(() =\u003e {\n          alert(JSON.stringify(values, null, 2));\n          setSubmitting(false);\n        }, 500);\n      }}\n    \u003e\n      \u003cForm\u003e\n        \u003ch3 id=\"color\"\u003eColor\u003c/h3\u003e\n        \u003cFRadioGroup name=\"color\"\u003e\n          \u003cRadio value=\"blue\"\u003eBlue\u003c/Radio\u003e\n          \u003cRadio value=\"red\"\u003eRed\u003c/Radio\u003e\n          \u003cRadio value=\"green\"\u003eGreen\u003c/Radio\u003e\n        \u003c/FRadioGroup\u003e\n      \u003c/Form\u003e\n    \u003c/Formik\u003e\n  );\n}\n```\n\n## API Reference\n\n### `\u003cRadioGroup /\u003e`\n\nThis renders a `div` and will pass through all props to the DOM element. It's children must be `\u003cRadio\u003e` components.\n\n#### `labelledBy?: string`\n\nThis should match the `id` you used to label the radio group.\n\n```tsx\n\u003ch3 id=\"color\"\u003eColor\u003c/h3\u003e\n\u003cRadioGroup labelledBy=\"color\"\u003e\n  {/* ... */}\n\u003c/RadioGroup\u003e\n```\n\n#### `onChange: (value: any) =\u003e void`\n\nA callback function that will be fired with the `value` of the newly selected item.\n\n```tsx\nimport * as React from 'react';\nimport { RadioGroup, Radio } from '@palmerhq/radio-group';\nimport '@palmerhq/radio-group/styles.css'; // use the default styles\n\nfunction App() {\n  const [value, setValue] = React.useState\u003cstring | undefined\u003e();\n\n  return (\n    \u003c\u003e\n      \u003ch3 id=\"color\"\u003eColor\u003c/h3\u003e\n      \u003cRadioGroup\n        labelledBy=\"color\"\n        value={value}\n        onChange={value =\u003e setValue(value)}\n      \u003e\n        \u003cRadio value=\"blue\"\u003eBlue\u003c/Radio\u003e\n        \u003cRadio value=\"red\"\u003eRed\u003c/Radio\u003e\n        \u003cRadio value=\"green\"\u003eGreen\u003c/Radio\u003e\n      \u003c/RadioGroup\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n#### `children: React.ComponentType\u003cRadioProps\u003e[]`\n\n**Required**\n\nThe children of a `\u003cRadioGroup\u003e` can **ONLY** be `\u003cRadio\u003e` components. In order to support compliant keyboard behavior, each sibling must know the value of the whole group and so `React.Children.map` is used internally.\n\n```tsx\n\u003ch3 id=\"color\"\u003eColor\u003c/h3\u003e\n\u003cRadioGroup labelledBy=\"color\"\u003e\n  {/* ... */}\n\u003c/RadioGroup\u003e\n```\n\n#### `value: any`\n\n**Required**\n\nThe current value of the radio group. This is shallowly compared to each `value` prop of the child `\u003cRadio\u003e` components to determine which item is active.\n\n#### `as?: React.ComponentType`\n\nComponent to use a the wrapper. Default is `\u003cdiv\u003e`.\n\n#### `autoFocus?: boolean`\n\nWhether to autoFocus the selected radio option.\n\n### `\u003cRadio\u003e`\n\nThis renders a `div` with a data attribute `data-palmerhq-radio` and all the relevant perfect aria attributes. The React component will pass through all props to the DOM element.\n\n#### `value: any`\n\n**Required**\n\nThe value of the radio button. This will be set / passed back to the `\u003cRadioGroup onChange\u003e` when the item is selected.\n\n#### `onFocus?: () =\u003e void`\n\nCallback function for when the item is focused. When focused, a data attribute `data-palmerhq-radio-focus` is set to `\"true\"`. You can thus apply the selector to manage focus style like so:\n\n```css\n[data-palmerhq-radio][data-palmerhq-radio-focus='true'] {\n  background: blue;\n}\n```\n\n#### `onBlur?: () =\u003e void`\n\nCallback function for when the item is blurred\n\n#### `as?: React.ComponentType`\n\nComponent to use as radio. Default is `\u003cdiv\u003e`.\n\n### Underlying DOM Structure\n\nFor reference, the underlying HTML DOM structure are all `div`s and looks as follows.\n\n```html\n\u003cdiv role=\"radiogroup\" aria-labelledby=\"color\" data-palmerhq-radio-group=\"true\"\u003e\n  \u003cdiv\n    role=\"radio\"\n    tabindex=\"0\"\n    aria-checked=\"false\"\n    data-palmerhq-radio=\"true\"\n    data-palmerhq-radio-focus=\"false\"\n  \u003e\n    Red\n  \u003c/div\u003e\n  \u003cdiv\n    role=\"radio\"\n    tabindex=\"-1\"\n    aria-checked=\"false\"\n    data-palmerhq-radio=\"true\"\n    data-palmerhq-radio-focus=\"false\"\n  \u003e\n    Green\n  \u003c/div\u003e\n  \u003cdiv\n    role=\"radio\"\n    tabindex=\"-1\"\n    aria-checked=\"false\"\n    data-palmerhq-radio=\"true\"\n    data-palmerhq-radio-focus=\"false\"\n  \u003e\n    Blue\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n### Overriding Styles\n\nThese are the default styles. Copy and paste the following into your app to customize them.\n\n```css\n[data-palmerhq-radio-group] {\n  padding: 0;\n  margin: 0;\n  list-style: none;\n}\n\n[data-palmerhq-radio-group]:focus {\n  outline: none;\n}\n\n[data-palmerhq-radio] {\n  border: 2px solid transparent;\n  border-radius: 5px;\n  display: inline-block;\n  position: relative;\n  padding: 0.125em;\n  padding-left: 1.5em;\n  padding-right: 0.5em;\n  cursor: default;\n  outline: none;\n}\n\n[data-palmerhq-radio] + [data-palmerhq-radio] {\n  margin-left: 1em;\n}\n\n[data-palmerhq-radio]::before,\n[data-palmerhq-radio]::after {\n  position: absolute;\n  top: 50%;\n  left: 7px;\n  transform: translate(-20%, -50%);\n  content: '';\n}\n\n[data-palmerhq-radio]::before {\n  width: 14px;\n  height: 14px;\n  border: 1px solid hsl(0, 0%, 66%);\n  border-radius: 100%;\n  background-image: linear-gradient(to bottom, hsl(300, 3%, 93%), #fff 60%);\n}\n\n[data-palmerhq-radio]:active::before {\n  background-image: linear-gradient(\n    to bottom,\n    hsl(300, 3%, 73%),\n    hsl(300, 3%, 93%)\n  );\n}\n\n[data-palmerhq-radio][aria-checked='true']::before {\n  border-color: hsl(216, 80%, 50%);\n  background: hsl(217, 95%, 68%);\n  background-image: linear-gradient(\n    to bottom,\n    hsl(217, 95%, 68%),\n    hsl(216, 80%, 57%)\n  );\n}\n\n[data-palmerhq-radio][aria-checked='true']::after {\n  display: block;\n  border: 0.1875em solid #fff;\n  border-radius: 100%;\n  transform: translate(25%, -50%);\n}\n\n[data-palmerhq-radio][aria-checked='mixed']:active::before,\n[data-palmerhq-radio][aria-checked='true']:active::before {\n  background-image: linear-gradient(\n    to bottom,\n    hsl(216, 80%, 57%),\n    hsl(217, 95%, 68%) 60%\n  );\n}\n\n[data-palmerhq-radio]:hover::before {\n  border-color: hsl(216, 94%, 65%);\n}\n\n[data-palmerhq-radio][data-palmerhq-radio-focus='true'] {\n  border-color: hsl(216, 94%, 73%);\n  background-color: hsl(216, 80%, 97%);\n}\n\n[data-palmerhq-radio]:hover {\n  background-color: hsl(216, 80%, 92%);\n}\n```\n\n## Accessibility Features\n\n- Uses CSS attribute selectors for synchronizing `aria-checked` state with the visual state indicator.\n- Uses CSS `:hover` and `:focus` pseudo-selectors for styling visual keyboard focus and hover.\n- Focus indicator encompasses both radio button and label, making it easier to perceive which option is being chosen.\n- Hover changes background of both radio button and label, making it easier to perceive that clicking either the label or button will activate the radio button.\n\n\u003ch2 id=\"kbd_label\"\u003eKeyboard Support\u003c/h2\u003e\n\n\u003ctable aria-labelledby=\"kbd_label\" class=\"def\"\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eKey\u003c/th\u003e\n      \u003cth\u003eFunction\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr data-test-id=\"key-tab\"\u003e\n      \u003cth\u003e\u003ckbd\u003eTab\u003c/kbd\u003e\u003c/th\u003e\n      \u003ctd\u003e\n        \u003cul\u003e\n          \u003cli\u003eMoves focus to the checked \u003ccode\u003eradio\u003c/code\u003e button in the \u003ccode\u003eradiogroup\u003c/code\u003e.\u003c/li\u003e\n          \u003cli\u003eIf a \u003ccode\u003eradio\u003c/code\u003e button is not checked, focus moves to the first \u003ccode\u003eradio\u003c/code\u003e button in the group.\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr data-test-id=\"key-space\"\u003e\n      \u003cth\u003e\u003ckbd\u003eSpace\u003c/kbd\u003e\u003c/th\u003e\n      \u003ctd\u003e\n        \u003cul\u003e\n          \u003cli\u003eIf the \u003ccode\u003eradio\u003c/code\u003e button with focus is not checked, changes the state to \u003ccode\u003echecked\u003c/code\u003e.\u003c/li\u003e\n          \u003cli\u003eOtherwise, does nothing.\u003c/li\u003e\n          \u003cli\u003eNote: The state where a radio is not checked only occurs on page load.\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr data-test-id=\"key-right-arrow\"\u003e\n      \u003cth\u003e\u003ckbd\u003eRight arrow\u003c/kbd\u003e\u003c/th\u003e\n      \u003ctd\u003e\n        \u003cul\u003e\n          \u003cli\u003eMoves focus to and checks the next \u003ccode\u003eradio\u003c/code\u003e button in the group.\u003c/li\u003e\n          \u003cli\u003eIf focus is on the last \u003ccode\u003eradio\u003c/code\u003e button, moves focus to the first \u003ccode\u003eradio\u003c/code\u003e button.\u003c/li\u003e\n          \u003cli\u003eThe state of the previously checked radio button is changed to unchecked.\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr data-test-id=\"key-down-arrow\"\u003e\n      \u003cth\u003e\u003ckbd\u003eDown arrow\u003c/kbd\u003e\u003c/th\u003e\n      \u003ctd\u003e\n        \u003cul\u003e\n          \u003cli\u003eMoves focus to and checks the next \u003ccode\u003eradio\u003c/code\u003e button in the group.\u003c/li\u003e\n          \u003cli\u003eIf focus is on the last \u003ccode\u003eradio\u003c/code\u003e button, moves focus to the first \u003ccode\u003eradio\u003c/code\u003e button.\u003c/li\u003e\n          \u003cli\u003eThe state of the previously checked radio button is changed to unchecked.\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr data-test-id=\"key-left-arrow\"\u003e\n      \u003cth\u003e\u003ckbd\u003eLeft arrow\u003c/kbd\u003e\u003c/th\u003e\n      \u003ctd\u003e\n        \u003cul\u003e\n          \u003cli\u003eMoves focus to and checks the previous \u003ccode\u003eradio\u003c/code\u003e button in the group.\u003c/li\u003e\n          \u003cli\u003eIf focus is on the first \u003ccode\u003eradio\u003c/code\u003e button, moves focus to and checks the last \u003ccode\u003eradio\u003c/code\u003e button.\u003c/li\u003e\n          \u003cli\u003eThe state of the previously checked radio button is changed to unchecked.\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr data-test-id=\"key-up-arrow\"\u003e\n      \u003cth\u003e\u003ckbd\u003eUp arrow\u003c/kbd\u003e\u003c/th\u003e\n      \u003ctd\u003e\n        \u003cul\u003e\n          \u003cli\u003eMoves focus to and checks the previous \u003ccode\u003eradio\u003c/code\u003e button in the group.\u003c/li\u003e\n          \u003cli\u003eIf focus is on the first \u003ccode\u003eradio\u003c/code\u003e button, moves focus to and checks the last \u003ccode\u003eradio\u003c/code\u003e button.\u003c/li\u003e\n          \u003cli\u003eThe state of the previously checked radio button is changed to unchecked.\u003c/li\u003e\n        \u003c/ul\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003ch2 id=\"rps_label\"\u003eRole, Property, State, and Tabindex  Attributes\u003c/h2\u003e\n\u003ctable aria-labelledby=\"rps_label\" class=\"data attributes\"\u003e\n\u003cthead\u003e\n  \u003ctr\u003e\n    \u003cth scope=\"col\"\u003eRole\u003c/th\u003e\n    \u003cth scope=\"col\"\u003eAttributes\u003c/th\u003e\n    \u003cth scope=\"col\"\u003eElement\u003c/th\u003e\n    \u003cth scope=\"col\"\u003eUsage\u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n  \u003ctr data-test-id=\"radiogroup-role\"\u003e\n    \u003cth scope=\"row\"\u003e\u003ccode\u003eradiogroup\u003c/code\u003e\u003c/th\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003cul\u003e\n        \u003cli\u003eIdentifies the \u003ccode\u003ediv\u003c/code\u003e element as a container for a group of \u003ccode\u003eradio\u003c/code\u003e buttons.\u003c/li\u003e\n        \u003cli\u003eIs not focusable because focus is managed using a roving tabindex strategy as described below.\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr data-test-id=\"radiogroup-aria-labelledby\"\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003cth scope=\"row\"\u003e\u003ccode\u003earia-labelledby=\"[IDREF]\"\u003c/code\u003e\u003c/th\u003e\n    \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003eRefers to the element that contains the label of the radio group.\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr data-test-id=\"radio-role\"\u003e\n    \u003cth scope=\"row\"\u003e\u003ccode\u003eradio\u003c/code\u003e\u003c/th\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003cul\u003e\n        \u003cli\u003eIdentifies the \u003ccode\u003ediv\u003c/code\u003e element as an ARIA \u003ccode\u003eradio\u003c/code\u003e button.\u003c/li\u003e\n        \u003cli\u003eThe accessible name is computed from the child text content of the \u003ccode\u003ediv\u003c/code\u003e element.\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr data-test-id=\"radio-tabindex\"\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003cth scope=\"row\"\u003e\u003ccode\u003etabindex=\"-1\"\u003c/code\u003e\u003c/th\u003e\n    \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003cul\u003e\n        \u003cli\u003eMakes the element focusable but not part of the page \u003ckbd\u003eTab\u003c/kbd\u003e sequence.\u003c/li\u003e\n        \u003cli\u003eApplied to all radio buttons contained in the radio group except for one that is included in the page \u003ckbd\u003eTab\u003c/kbd\u003e sequence.\u003c/li\u003e\n        \u003cli\u003eThis approach to managing focus is described in the section on \u003ca href=\"https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_roving_tabindex\"\u003eroving tabindex\u003c/a\u003e.\u003c/li\u003e\n      \u003c/ul\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr data-test-id=\"radio-tabindex\"\u003e\n    \u003ctd\u003e\u003c/td\u003e\n    \u003cth scope=\"row\"\u003e\u003ccode\u003etabindex=\"0\"\u003c/code\u003e\u003c/th\u003e\n    \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n    \u003ctd\u003e\n      \u003cul\u003e\n        \u003cli\u003eMakes the radio button focusable and includes it in the page \u003ckbd\u003eTab\u003c/kbd\u003e sequence.\u003c/li\u003e\n        \u003cli\u003eSet on only one radio in the radio group.\u003c/li\u003e\n        \u003cli\u003eOn page load, is set on the first radio button in the radio group.\u003c/li\u003e\n        \u003cli\u003eMoves with focus inside the radio group so the most recently focused radio button is included in the page \u003ckbd\u003eTab\u003c/kbd\u003e sequence.\u003c/li\u003e\n        \u003cli\u003eThis approach to managing focus is described in the section on \u003ca href=\"https://www.w3.org/TR/wai-aria-practices-1.1/#kbd_roving_tabindex\"\u003eroving tabindex\u003c/a\u003e.\u003c/li\u003e\n                \u003c/ul\u003e\n              \u003c/td\u003e\n            \u003c/tr\u003e\n            \u003ctr data-test-id=\"radio-aria-checked\"\u003e\n              \u003ctd\u003e\u003c/td\u003e\n              \u003cth scope=\"row\"\u003e\u003ccode\u003earia-checked=\"false\"\u003c/code\u003e\u003c/th\u003e\n              \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n              \u003ctd\u003e\n                \u003cul\u003e\n                  \u003cli\u003eIdentifies \u003ccode\u003eradio\u003c/code\u003e buttons which are not checked.\u003c/li\u003e\n                  \u003cli\u003eCSS attribute selectors (e.g. \u003ccode\u003e[aria-checked=\"false\"]\u003c/code\u003e) are used to synchronize the visual states with the value of the \u003ccode\u003earia-checked\u003c/code\u003e attribute.\u003c/li\u003e\n                  \u003cli\u003eThe CSS \u003ccode\u003e::before\u003c/code\u003e pseudo-class is used to indicate visual state of unchecked radio buttons to support high contrast settings in operating systems and browsers.\u003c/li\u003e\n                \u003c/ul\u003e\n              \u003c/td\u003e\n            \u003c/tr\u003e\n            \u003ctr data-test-id=\"radio-aria-checked\"\u003e\n              \u003ctd\u003e\u003c/td\u003e\n              \u003cth scope=\"row\"\u003e\u003ccode\u003earia-checked=\"true\"\u003c/code\u003e\u003c/th\u003e\n              \u003ctd\u003e\u003ccode\u003ediv\u003c/code\u003e\u003c/td\u003e\n              \u003ctd\u003e\n                \u003cul\u003e\n                  \u003cli\u003eIdentifies the \u003ccode\u003eradio\u003c/code\u003e button which is checked.\u003c/li\u003e\n                  \u003cli\u003eCSS attribute selectors (e.g. \u003ccode\u003e[aria-checked=\"true\"]\u003c/code\u003e) are used to synchronize the visual states with the value of the \u003ccode\u003earia-checked\u003c/code\u003e attribute.\u003c/li\u003e\n                  \u003cli\u003eThe CSS \u003ccode\u003e::before\u003c/code\u003e pseudo-class is used to indicate visual state of checked radio buttons to support high contrast settings in operating systems and browsers.\u003c/li\u003e\n                \u003c/ul\u003e\n              \u003c/td\u003e\n            \u003c/tr\u003e\n          \u003c/tbody\u003e\n        \u003c/table\u003e\n\n## Authors\n\n- Jared Palmer ([@jaredpalmer](https://twitter.com/jaredpalmer))\n\n---\n\n\u003e MIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpalmerhq%2Fradio-group","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpalmerhq%2Fradio-group","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpalmerhq%2Fradio-group/lists"}