Skip to content

Commit 094934c

Browse files
eirikbackermimarz
authored andcommitted
fix(Radio+Checkbox): use input component (#2607)
- Part of #2311 - Fieldset at compound components moved to task #2666 - Fixes #2459
1 parent 4b14b02 commit 094934c

39 files changed

+966
-1966
lines changed

.changeset/shiny-dryers-count.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@digdir/designsystemet-css": major
3+
"@digdir/designsystemet-react": major
4+
---
5+
6+
Radio + Checkbox:
7+
- Use `label` prop instead of `children` as label text
8+
- Remove `Radio.Group` and `Checkbox.Group` and use `Fieldset` instead

apps/theme/components/Previews/Components/Components.tsx

+15-25
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import { useState } from 'react';
3535
import classes from './Components.module.css';
3636

3737
export const Components = () => {
38-
const [radioValue, setRadioValue] = useState('vanilje');
3938
const [currentPage, setCurrentPage] = useState(1);
4039
const pagination = usePagination({
4140
currentPage,
@@ -47,21 +46,15 @@ export const Components = () => {
4746
return (
4847
<div className={classes.components}>
4948
<div className={cl(classes.card, classes.checkbox)}>
50-
<Checkbox.Group error='' legend='Handleliste' size='sm'>
51-
<Checkbox value='epost'>En kilo poteter</Checkbox>
52-
<Checkbox value='telefon'>To liter Farris</Checkbox>
53-
<Checkbox value='sms' defaultChecked>
54-
Blomkål
55-
</Checkbox>
56-
<Checkbox value='sms' defaultChecked>
57-
Pizza
58-
</Checkbox>
59-
<Checkbox value='sms' defaultChecked>
60-
Tre liter lettmelk
61-
</Checkbox>
62-
<Checkbox value='sms'>2kg smågodt</Checkbox>
63-
<Checkbox value='sms'>10 poser med Smash</Checkbox>
64-
</Checkbox.Group>
49+
<Fieldset legend='Handleliste' size='sm'>
50+
<Checkbox label='En kilo poteter' value='epost' />
51+
<Checkbox label='To liter Farris' value='telefon' />
52+
<Checkbox label='Blomkål' value='sms' defaultChecked />
53+
<Checkbox label='Pizza' value='sms' defaultChecked />
54+
<Checkbox label='Tre liter lettmelk' value='sms' defaultChecked />
55+
<Checkbox label='2kg smågodt' value='sms' />
56+
<Checkbox label='10 poser med Smash' value='sms' />
57+
</Fieldset>
6558
</div>
6659
<div className={cl(classes.card, classes.user)}>
6760
<Heading className={cl(classes.cardTitle, classes.userTitle)} size='xs'>
@@ -205,19 +198,16 @@ export const Components = () => {
205198
</div>
206199
</div>
207200
<div className={cl(classes.card, classes.radio)}>
208-
<Radio.Group
209-
error=''
201+
<Fieldset
210202
legend='Hvilken iskremsmak er best?'
211203
description='Velg din favorittsmak'
212204
size='sm'
213-
value={radioValue}
214-
onChange={(e: string) => setRadioValue(e)}
215205
>
216-
<Radio value='vanilje'>Vanilje</Radio>
217-
<Radio value='jordbær'>Jordbær</Radio>
218-
<Radio value='sjokolade'>Sjokolade</Radio>
219-
<Radio value='spiser-ikke-is'>Jeg spiser ikke iskrem</Radio>
220-
</Radio.Group>
206+
<Radio label='Vanile' value='vanilje' />
207+
<Radio label='Jordbær' value='jordbær' defaultChecked />
208+
<Radio label='Sjokolade' value='sjokolade' />
209+
<Radio label='Jeg spiser ikke iskrem' value='spiser-ikke-is' />
210+
</Fieldset>
221211
</div>
222212
<div className={cl(classes.card, classes.tag)}>
223213
<Heading size='xs' className={classes.tagHeading}>

packages/css/checkbox.css

-221
This file was deleted.

packages/css/field.css

+67-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,71 @@
11
.ds-field {
2-
display: contents;
2+
align-items: start;
3+
display: flex;
4+
flex-direction: column;
5+
gap: var(--ds-spacing-2);
36

4-
& > * + * {
5-
margin-top: var(--ds-spacing-2);
7+
@composes ds-body-text--md from './base/base.css';
8+
9+
&[data-size='sm'] {
10+
@composes ds-body-text--sm from './base/base.css';
11+
}
12+
13+
&[data-size='lg'] {
14+
@composes ds-body-text--lg from './base/base.css';
15+
}
16+
17+
& [data-field='description'] {
18+
color: var(--ds-color-neutral-text-subtle); /* TODO: Change to opacity or color-mix(currentColor, trasparent) to ensure contrast when parent element color changes? */
19+
}
20+
21+
/**
22+
* States
23+
*/
24+
&:has([aria-disabled='true'], :disabled) > * {
25+
cursor: not-allowed;
26+
opacity: var(--ds-disabled-opacity);
27+
}
28+
29+
&:has([aria-readonly='true'], [readonly]) label {
30+
--dsc-label--readonly: ; /* Activate lock icon for label when readonly */
31+
}
32+
33+
/**
34+
* Toggle inputs
35+
*/
36+
&:has(input:is([type='radio'], [type='checkbox'])) {
37+
border-radius: var(--ds-border-radius-md);
38+
display: grid;
39+
grid-template-columns: auto 1fr;
40+
row-gap: 0;
41+
width: fit-content; /* Rather do display: grid + width: fit-content than display: inline-grid to encourage stacked radios */
42+
43+
& > * {
44+
grid-column: 2; /* Only allow input in column 1 */
45+
}
46+
47+
& label {
48+
--dsc-label--readonly: initial; /* Never show lock icon on toggle inputs */
49+
font-weight: var(--ds-font-weight-regular);
50+
}
51+
52+
& input {
53+
grid-column: 1; /* Always place input in column 1 */
54+
grid-row: 1; /* Always place input in row 1 */
55+
outline: none;
56+
box-shadow: none;
57+
}
58+
59+
&:not(:has([readonly], [aria-disabled='true'], :disabled)) label {
60+
cursor: pointer;
61+
}
62+
63+
&:has(input:focus-visible) {
64+
@composes ds-focus--visible from './base/base.css';
65+
}
66+
67+
&:has(input:only-child) {
68+
gap: 0; /* No gap only <input> with aria-label/aria-labelledby */
69+
}
670
}
771
}

0 commit comments

Comments
 (0)