@@ -2,13 +2,11 @@ import clsx from 'clsx';
2
2
import React from 'react' ;
3
3
import { useId } from '../../util/useId' ;
4
4
import type { EitherInclusive } from '../../util/utility-types' ;
5
- import type { RadioInputProps } from '../RadioInput' ;
6
- import RadioInput from '../RadioInput' ;
7
- import type { RadioLabelProps } from '../RadioLabel' ;
8
- import RadioLabel from '../RadioLabel' ;
5
+ import Icon from '../Icon' ;
6
+ import { InputLabel , type InputLabelProps } from '../InputLabel/InputLabel' ;
9
7
import styles from './Radio.module.css' ;
10
8
11
- export type RadioProps = RadioInputProps & {
9
+ type RadioProps = RadioInputProps & {
12
10
/**
13
11
* HTML id attribute. If not passed, this component
14
12
* will generate an id to use for accessibility.
@@ -17,7 +15,7 @@ export type RadioProps = RadioInputProps & {
17
15
/**
18
16
* Size of the radio label.
19
17
*/
20
- size ?: RadioLabelProps [ 'size' ] ;
18
+ size ?: InputLabelProps [ 'size' ] ;
21
19
} & EitherInclusive <
22
20
{
23
21
/**
@@ -32,6 +30,86 @@ export type RadioProps = RadioInputProps & {
32
30
'aria-label' : string ;
33
31
}
34
32
> ;
33
+ type RadioInputProps = Omit <
34
+ React . InputHTMLAttributes < HTMLInputElement > ,
35
+ 'id' | 'size'
36
+ > & {
37
+ /**
38
+ * Additional classnames passed in for styling.
39
+ */
40
+ className ?: string ;
41
+ /**
42
+ * Radio ID. Used to connect the input with a label for accessibility purposes.
43
+ */
44
+ id ?: string ;
45
+ } ;
46
+
47
+ const RadioSvg = ( {
48
+ checked,
49
+ disabled,
50
+ } : {
51
+ checked ?: boolean ;
52
+ disabled ?: boolean ;
53
+ } ) => {
54
+ const iconClassName = clsx (
55
+ styles [ 'radio__icon' ] ,
56
+ disabled && styles [ 'radio__icon--disabled' ] ,
57
+ ) ;
58
+ return (
59
+ < Icon
60
+ className = { iconClassName }
61
+ name = { checked ? 'radio-selected' : 'radio-unselected' }
62
+ purpose = "decorative"
63
+ size = "1.625rem"
64
+ />
65
+ ) ;
66
+ } ;
67
+
68
+ /**
69
+ * Radio input element, exported for greater flexibility.
70
+ * You must provide an `id` prop and connect it to a visible label.
71
+ */
72
+ export const RadioInput = ( {
73
+ checked = false ,
74
+ className,
75
+ disabled,
76
+ ...other
77
+ } : RadioInputProps ) => {
78
+ return (
79
+ < span
80
+ className = { clsx (
81
+ styles [ 'input__wrapper' ] ,
82
+ disabled && styles [ 'input__wrapper--disabled' ] ,
83
+ ) }
84
+ >
85
+ < input
86
+ checked = { checked }
87
+ className = { clsx ( className , styles [ 'radio__input' ] ) }
88
+ disabled = { disabled }
89
+ type = "radio"
90
+ { ...other }
91
+ />
92
+ < RadioSvg checked = { checked } disabled = { disabled } />
93
+ </ span >
94
+ ) ;
95
+ } ;
96
+
97
+ /**
98
+ * Radio label element, styles and relies on the InputLabel component.
99
+ */
100
+ export const RadioLabel = ( {
101
+ className,
102
+ size = 'lg' ,
103
+ ...other
104
+ } : InputLabelProps ) => {
105
+ const componentClassName = clsx (
106
+ styles [ 'radio__label' ] ,
107
+ styles [ `radio__label--${ size } ` ] ,
108
+ className ,
109
+ ) ;
110
+
111
+ return < InputLabel className = { componentClassName } size = { size } { ...other } /> ;
112
+ } ;
35
113
36
114
/**
37
115
* `import {Radio} from "@chanzuckerberg/eds";`
0 commit comments