Skip to content

Commit

Permalink
fix(radio): use styled inputs instead of pseudo-elements
Browse files Browse the repository at this point in the history
Applying styling to the input directly will help us with:

- Running unit tests that use accessibility-based selectors (those tend
  to fail with hidden elements)
- Use the radio independently of the label
- Avoid the need of having a relatively positioned wrapper container

BREAKING CHANGE: While the markup and styling for using radios remains
unchanged, there is one edge case where you will need to update your
radio usage, which is if you expect the label to span multiple lines.
Please refer to the docs for more information.
  • Loading branch information
andreasphil committed Jul 13, 2023
1 parent 235dfd4 commit d53ef18
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 41 deletions.
25 changes: 22 additions & 3 deletions docs/pages/components/radio.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ layout: layouts/sidebar.njk
<label for="r1">Lorem ipsum</label>
```

#### with multiple lines

If the label text is too long to fit on one line, wrap the radio and label in a container (e.g. a `div` or a `span`) containing nothing else. This will prevent the label text from wrapping under the radio.

```
<div>
<input type="radio" name="radios" value="4" id="r3" class="ds-radio" />
<label for="r3">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tincidunt
cursus mi, a dictum magna venenatis vitae. Nunc a sollicitudin libero. In
a risus iaculis felis eleifend sodales. Morbi ullamcorper congue viverra.
Aliquam ullamcorper, neque ac rutrum hendrerit, erat mauris euismod quam,
at aliquam diam mauris et magna.
</label>
</div>
```

Note that this uses the `has` selector, which is only available on recent versions of Chrome and Safari for now. If you need to support Firefox or older browsers, add the `flex` class to the wrapping container instead.

### Regular size (default)

<div class="ds-stack-24">
Expand All @@ -46,7 +65,7 @@ layout: layouts/sidebar.njk
<label for="r1">Lorem ipsum 2</label>
</div>

<div>
<div class="flex">
<input type="radio" name="radios" value="4" id="r3" class="ds-radio" />
<label for="r3">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tincidunt
Expand Down Expand Up @@ -76,7 +95,7 @@ layout: layouts/sidebar.njk
<label for="sr1">Lorem ipsum 2</label>
</div>

<div>
<div class="flex">
<input type="radio" name="sradios" value="4" id="sr3" class="ds-radio ds-radio-small" />
<label for="sr3">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tincidunt
Expand Down Expand Up @@ -106,7 +125,7 @@ layout: layouts/sidebar.njk
<label for="mr1">Lorem ipsum 2</label>
</div>

<div>
<div class="flex">
<input type="radio" name="mradios" value="4" id="mr3" class="ds-radio ds-radio-mini" />
<label for="mr3">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris tincidunt
Expand Down
78 changes: 40 additions & 38 deletions src/components/radio.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,83 @@
const a11y = require("../utils/a11y");

module.exports = function ({ addComponents, theme }) {
addComponents({
".ds-radio": a11y.srOnly,
".ds-radio + label, .ds-radio + label::before, .ds-radio + label::after": {
".ds-radio, .ds-radio + label, .ds-radio::after": {
"--radio-ring-radius": "1.25rem",
"--radio-ring-diameter": "calc(var(--radio-ring-radius) * 2)",
"--radio-dot-radius": "0.75rem",
"--radio-text-padding-left": "1rem",
"--radio-text-padding-top": "0.4375rem",
},
".ds-radio": {
appearance: "none",
width: "var(--radio-ring-diameter)",
height: "var(--radio-ring-diameter)",
boxShadow: `inset 0 0 0 0.125rem ${theme("colors.blue.800")}`,
position: "relative",
outline: "none",
cursor: "pointer",
borderRadius: "50%",
float: "left",
flex: "none",
},
".ds-radio + label": {
position: "relative",
display: "inline-block",
paddingTop: "var(--radio-text-padding-top)",
paddingLeft:
"calc(var(--radio-ring-diameter) + var(--radio-text-padding-left))",
paddingLeft: "var(--radio-text-padding-left)",
minHeight: "var(--radio-ring-diameter)",
touchAction: "manipulation",
cursor: "pointer",
verticalAlign: "top",
float: "left",
},
".ds-radio + label::before, .ds-radio + label::after": {
".ds-radio::after": {
content: '""',
display: "block",
position: "absolute",
top: "var(--radio-ring-radius)",
left: "0",
transform: "translateY(-50%)",
},
".ds-radio + label::before": {
left: "0",
width: "var(--radio-ring-diameter)",
height: "var(--radio-ring-diameter)",
boxShadow: `inset 0 0 0 0.125rem ${theme("colors.blue.800")}`,
borderRadius: "50%",
".ds-radio:focus, .ds-radio:focus-visible": {
boxShadow: `inset 0 0 0 0.25rem ${theme("colors.blue.800")}`,
},
".ds-radio:focus + label::before, .ds-radio:focus-visible + label::before":
{
boxShadow: `inset 0 0 0 0.25rem ${theme("colors.blue.800")}`,
},
".ds-radio:checked + label::after": {
".ds-radio:checked::after": {
left: "calc(var(--radio-ring-radius) - var(--radio-dot-radius))",
width: "0",
height: "0",
border: `solid var(--radio-dot-radius) ${theme("colors.blue.800")}`,
backgroundColor: theme("colors.blue.800"),
borderRadius: "50%",
},
".ds-radio[disabled] + label": {
".ds-radio[disabled], .ds-radio[disabled] + label": {
cursor: "default",
},
".ds-radio[disabled] + label::before": {
".ds-radio[disabled]": {
boxShadow: `inset 0 0 0 0.125rem ${theme("colors.gray.600")}`,
},
".ds-radio[disabled] + label::after": {
".ds-radio[disabled]::after": {
borderColor: theme("colors.gray.600"),
backgroundColor: theme("colors.gray.600"),
},
".ds-radio:not(:disabled):hover + label::before": {
".ds-radio:not(:disabled):hover": {
boxShadow: `inset 0 0 0 0.25rem ${theme("colors.blue.800")}`,
},
".ds-radio:not(:focus-visible):focus + label::before": {
".ds-radio:not(:focus-visible):focus": {
boxShadow: `inset 0 0 0 0.125rem ${theme("colors.blue.800")}`,
},
".ds-radio-small + label, .ds-radio-small + label::before, .ds-radio-small + label::after":
{
"--radio-ring-radius": "1rem",
"--radio-dot-radius": "0.5rem",
"--radio-text-padding-left": "0.75rem",
"--radio-text-padding-top": "0.3125rem",
},
".ds-radio-mini + label, .ds-radio-mini + label::before, .ds-radio-mini + label::after":
{
"--radio-ring-radius": "0.75rem",
"--radio-dot-radius": "0.3125rem",
"--radio-text-padding-left": "0.625rem",
"--radio-text-padding-top": "0.0625rem",
},
".ds-radio-small, .ds-radio-small + label, .ds-radio-small::after": {
"--radio-ring-radius": "1rem",
"--radio-dot-radius": "0.5rem",
"--radio-text-padding-left": "0.75rem",
"--radio-text-padding-top": "0.3125rem",
},
" .ds-radio-mini, .ds-radio-mini + label, .ds-radio-mini::after": {
"--radio-ring-radius": "0.75rem",
"--radio-dot-radius": "0.3125rem",
"--radio-text-padding-left": "0.625rem",
"--radio-text-padding-top": "0.0625rem",
},
":has(> .ds-radio + label):has(> :nth-child(2):last-child)": {
display: "flex",
},
});
};

0 comments on commit d53ef18

Please sign in to comment.