Security News
Supply Chain Attack Detected in Solana's web3.js Library
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
@palmerhq/radio-group
Advanced tools
An accessible [WAI-ARIA 1.1-compliant Radio Group](https://www.w3.org/TR/wai-aria-practices-1.1/#radiobutton) React component.
@palmerhq/radio-group
An accessible WAI-ARIA 1.1-compliant Radio Group React component.
yarn add @palmerhq/radio-group
Or try it out in your browser on CodeSandbox
Note: This package uses
Array.prototype.findIndex
, so be sure that you have properly polyfilled.
import * as React from 'react';
import { RadioGroup, Radio } from '@palmerhq/radio-group';
import '@palmerhq/radio-group/styles.css'; // use the default styles
function App() {
const [value, setValue] = React.useState<string | undefined>();
return (
<>
<h3 id="color">Color</h3>
<RadioGroup
labelledBy="color"
value={value}
onChange={value => setValue(value)}
>
<Radio value="blue">Blue</Radio>
<Radio value="red">Red</Radio>
<Radio value="green">Green</Radio>
</RadioGroup>
</>
);
}
import * as React from 'react';
import { Formik, Form, useField } from 'formik';
import { RadioGroup, Radio } from '@palmerhq/radio-group';
import '@palmerhq/radio-group/styles.css'; // use the default styles
function FRadioGroup(props) {
const [{ onChange, onBlur, ...field }] = useField(props.name);
return (
<RadioGroup
{...props}
{...field}
labelledBy={props.name}
onBlur={onBlur(props.name)}
onChange={onChange(props.name)}
/>
);
}
function App() {
return (
<Formik
initialValues={{ color: '' }}
validationSchema={Yup.object().shape({
color: Yup.string().required(),
})}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 500);
}}
>
<Form>
<h3 id="color">Color</h3>
<FRadioGroup name="color">
<Radio value="blue">Blue</Radio>
<Radio value="red">Red</Radio>
<Radio value="green">Green</Radio>
</FRadioGroup>
</Form>
</Formik>
);
}
<RadioGroup />
This renders a div
and will pass through all props to the DOM element. It's children must be <Radio>
components.
labelledBy?: string
This should match the id
you used to label the radio group.
<h3 id="color">Color</h3>
<RadioGroup labelledBy="color">
{/* ... */}
</RadioGroup>
onChange: (value: any) => void
A callback function that will be fired with the value
of the newly selected item.
import * as React from 'react';
import { RadioGroup, Radio } from '@palmerhq/radio-group';
import '@palmerhq/radio-group/styles.css'; // use the default styles
function App() {
const [value, setValue] = React.useState<string | undefined>();
return (
<>
<h3 id="color">Color</h3>
<RadioGroup
labelledBy="color"
value={value}
onChange={value => setValue(value)}
>
<Radio value="blue">Blue</Radio>
<Radio value="red">Red</Radio>
<Radio value="green">Green</Radio>
</RadioGroup>
</>
);
}
children: React.ComponentType<RadioProps>[]
Required
The children of a <RadioGroup>
can ONLY be <Radio>
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.
<h3 id="color">Color</h3>
<RadioGroup labelledBy="color">
{/* ... */}
</RadioGroup>
value: any
Required
The current value of the radio group. This is shallowly compared to each value
prop of the child <Radio>
components to determine which item is active.
as?: React.ComponentType
Component to use a the wrapper. Default is <div>
.
autoFocus?: boolean
Whether to autoFocus the selected radio option.
<Radio>
This 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.
value: any
Required
The value of the radio button. This will be set / passed back to the <RadioGroup onChange>
when the item is selected.
onFocus?: () => void
Callback 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:
[data-palmerhq-radio][data-palmerhq-radio-focus='true'] {
background: blue;
}
onBlur?: () => void
Callback function for when the item is blurred
as?: React.ComponentType
Component to use as radio. Default is <div>
.
For reference, the underlying HTML DOM structure are all div
s and looks as follows.
<div role="radiogroup" aria-labelledby="color" data-palmerhq-radio-group="true">
<div
role="radio"
tabindex="0"
aria-checked="false"
data-palmerhq-radio="true"
data-palmerhq-radio-focus="false"
>
Red
</div>
<div
role="radio"
tabindex="-1"
aria-checked="false"
data-palmerhq-radio="true"
data-palmerhq-radio-focus="false"
>
Green
</div>
<div
role="radio"
tabindex="-1"
aria-checked="false"
data-palmerhq-radio="true"
data-palmerhq-radio-focus="false"
>
Blue
</div>
</div>
These are the default styles. Copy and paste the following into your app to customize them.
[data-palmerhq-radio-group] {
padding: 0;
margin: 0;
list-style: none;
}
[data-palmerhq-radio-group]:focus {
outline: none;
}
[data-palmerhq-radio] {
border: 2px solid transparent;
border-radius: 5px;
display: inline-block;
position: relative;
padding: 0.125em;
padding-left: 1.5em;
padding-right: 0.5em;
cursor: default;
outline: none;
}
[data-palmerhq-radio] + [data-palmerhq-radio] {
margin-left: 1em;
}
[data-palmerhq-radio]::before,
[data-palmerhq-radio]::after {
position: absolute;
top: 50%;
left: 7px;
transform: translate(-20%, -50%);
content: '';
}
[data-palmerhq-radio]::before {
width: 14px;
height: 14px;
border: 1px solid hsl(0, 0%, 66%);
border-radius: 100%;
background-image: linear-gradient(to bottom, hsl(300, 3%, 93%), #fff 60%);
}
[data-palmerhq-radio]:active::before {
background-image: linear-gradient(
to bottom,
hsl(300, 3%, 73%),
hsl(300, 3%, 93%)
);
}
[data-palmerhq-radio][aria-checked='true']::before {
border-color: hsl(216, 80%, 50%);
background: hsl(217, 95%, 68%);
background-image: linear-gradient(
to bottom,
hsl(217, 95%, 68%),
hsl(216, 80%, 57%)
);
}
[data-palmerhq-radio][aria-checked='true']::after {
display: block;
border: 0.1875em solid #fff;
border-radius: 100%;
transform: translate(25%, -50%);
}
[data-palmerhq-radio][aria-checked='mixed']:active::before,
[data-palmerhq-radio][aria-checked='true']:active::before {
background-image: linear-gradient(
to bottom,
hsl(216, 80%, 57%),
hsl(217, 95%, 68%) 60%
);
}
[data-palmerhq-radio]:hover::before {
border-color: hsl(216, 94%, 65%);
}
[data-palmerhq-radio][data-palmerhq-radio-focus='true'] {
border-color: hsl(216, 94%, 73%);
background-color: hsl(216, 80%, 97%);
}
[data-palmerhq-radio]:hover {
background-color: hsl(216, 80%, 92%);
}
aria-checked
state with the visual state indicator.:hover
and :focus
pseudo-selectors for styling visual keyboard focus and hover.Key | Function |
---|---|
Tab |
|
Space |
|
Right arrow |
|
Down arrow |
|
Left arrow |
|
Up arrow |
|
Role | Attributes | Element | Usage |
---|---|---|---|
radiogroup | div |
| |
aria-labelledby="[IDREF]" | div | Refers to the element that contains the label of the radio group. | |
radio | div |
| |
tabindex="-1" | div |
| |
tabindex="0" | div |
| |
aria-checked="false" | div |
| |
aria-checked="true" | div |
|
MIT License
FAQs
An accessible [WAI-ARIA 1.1-compliant Radio Group](https://www.w3.org/TR/wai-aria-practices-1.1/#radiobutton) React component.
We found that @palmerhq/radio-group demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A supply chain attack has been detected in versions 1.95.6 and 1.95.7 of the popular @solana/web3.js library.
Research
Security News
A malicious npm package targets Solana developers, rerouting funds in 2% of transactions to a hardcoded address.
Security News
Research
Socket researchers have discovered malicious npm packages targeting crypto developers, stealing credentials and wallet data using spyware delivered through typosquats of popular cryptographic libraries.