11import React from 'react'
2- import styled from 'styled-components'
3- import Box from '../../../Box'
42import ValidationAnimationContainer from '../ValidationAnimationContainer'
5- import { get } from '../../../constants'
63import { useId } from '../../../hooks/useId'
74import CheckboxOrRadioGroupCaption from './CheckboxOrRadioGroupCaption'
85import CheckboxOrRadioGroupLabel from './CheckboxOrRadioGroupLabel'
@@ -12,10 +9,8 @@ import VisuallyHidden from '../../../_VisuallyHidden'
129import { useSlots } from '../../../hooks/useSlots'
1310import type { SxProp } from '../../../sx'
1411import classes from './CheckboxOrRadioGroup.module.css'
15- import { toggleStyledComponent } from '../../utils/toggleStyledComponent'
16- import { useFeatureFlag } from '../../../FeatureFlags'
1712import { clsx } from 'clsx'
18- import { CSS_MODULES_FLAG } from './FeatureFlag '
13+ import { BoxWithFallback } from '../BoxWithFallback '
1914
2015export type CheckboxOrRadioGroupProps = {
2116 /** Class name for custom styling */
@@ -39,22 +34,6 @@ export type CheckboxOrRadioGroupProps = {
3934 required ?: boolean
4035} & SxProp
4136
42- const Body = toggleStyledComponent (
43- CSS_MODULES_FLAG ,
44- 'div' ,
45- styled . div `
46- display: flex;
47- flex-direction: column;
48- list-style: none;
49- margin: 0;
50- padding: 0;
51-
52- > * + * {
53- margin-top: ${ get ( 'space.2' ) } ;
54- }
55- ` ,
56- )
57-
5837const CheckboxOrRadioGroup : React . FC < React . PropsWithChildren < CheckboxOrRadioGroupProps > > = ( {
5938 'aria-labelledby' : ariaLabelledby ,
6039 children,
@@ -91,150 +70,6 @@ const CheckboxOrRadioGroup: React.FC<React.PropsWithChildren<CheckboxOrRadioGrou
9170
9271 const isLegendVisible = React . isValidElement ( labelChild ) && ! labelChild . props . visuallyHidden
9372
94- const enabled = useFeatureFlag ( CSS_MODULES_FLAG )
95-
96- if ( enabled ) {
97- if ( sx ) {
98- return (
99- < CheckboxOrRadioGroupContext . Provider
100- value = { {
101- disabled,
102- required,
103- captionId,
104- validationMessageId,
105- } }
106- >
107- < div >
108- < Box
109- className = { clsx ( className , classes . GroupFieldset ) }
110- data-validation = { validationChild ? '' : undefined }
111- { ...( labelChild
112- ? {
113- as : 'fieldset' ,
114- disabled,
115- }
116- : { } ) }
117- sx = { sx }
118- >
119- { labelChild ? (
120- /*
121- Placing the caption text and validation text in the <legend> provides a better user
122- experience for more screenreaders.
123-
124- Reference: https://blog.tenon.io/accessible-validation-of-checkbox-and-radiobutton-groups/
125- */
126- < legend className = { classes . GroupLegend } data-legend-visible = { isLegendVisible ? '' : undefined } >
127- { slots . label }
128- { slots . caption }
129- { React . isValidElement ( slots . validation ) && slots . validation . props . children && (
130- < VisuallyHidden > { slots . validation . props . children } </ VisuallyHidden >
131- ) }
132- </ legend >
133- ) : (
134- /*
135- If CheckboxOrRadioGroup.Label wasn't passed as a child, we don't render a <legend>
136- but we still want to render a caption
137- */
138- slots . caption
139- ) }
140-
141- < Body
142- className = { classes . Body }
143- { ...( ! labelChild
144- ? {
145- [ 'aria-labelledby' ] : ariaLabelledby ,
146- [ 'aria-describedby' ] : [ validationMessageId , captionId ] . filter ( Boolean ) . join ( ' ' ) ,
147- as : 'div' ,
148- role : 'group' ,
149- }
150- : { } ) }
151- >
152- { React . Children . toArray ( rest ) . filter ( child => React . isValidElement ( child ) ) }
153- </ Body >
154- </ Box >
155- { validationChild && (
156- < ValidationAnimationContainer
157- // If we have CheckboxOrRadioGroup.Label as a child, we render a screenreader-accessible validation message in the <legend>
158- aria-hidden = { Boolean ( labelChild ) }
159- show
160- >
161- { slots . validation }
162- </ ValidationAnimationContainer >
163- ) }
164- </ div >
165- </ CheckboxOrRadioGroupContext . Provider >
166- )
167- }
168- return (
169- < CheckboxOrRadioGroupContext . Provider
170- value = { {
171- disabled,
172- required,
173- captionId,
174- validationMessageId,
175- } }
176- >
177- < div >
178- < fieldset
179- className = { clsx ( className , classes . GroupFieldset ) }
180- data-validation = { validationChild ? '' : undefined }
181- { ...( labelChild
182- ? {
183- as : 'fieldset' ,
184- disabled,
185- }
186- : { } ) }
187- >
188- { labelChild ? (
189- /*
190- Placing the caption text and validation text in the <legend> provides a better user
191- experience for more screenreaders.
192-
193- Reference: https://blog.tenon.io/accessible-validation-of-checkbox-and-radiobutton-groups/
194- */
195- < legend className = { classes . GroupLegend } data-legend-visible = { isLegendVisible ? '' : undefined } >
196- { slots . label }
197- { slots . caption }
198- { React . isValidElement ( slots . validation ) && slots . validation . props . children && (
199- < VisuallyHidden > { slots . validation . props . children } </ VisuallyHidden >
200- ) }
201- </ legend >
202- ) : (
203- /*
204- If CheckboxOrRadioGroup.Label wasn't passed as a child, we don't render a <legend>
205- but we still want to render a caption
206- */
207- slots . caption
208- ) }
209-
210- < Body
211- className = { classes . Body }
212- { ...( ! labelChild
213- ? {
214- [ 'aria-labelledby' ] : ariaLabelledby ,
215- [ 'aria-describedby' ] : [ validationMessageId , captionId ] . filter ( Boolean ) . join ( ' ' ) ,
216- as : 'div' ,
217- role : 'group' ,
218- }
219- : { } ) }
220- >
221- { React . Children . toArray ( rest ) . filter ( child => React . isValidElement ( child ) ) }
222- </ Body >
223- </ fieldset >
224- { validationChild && (
225- < ValidationAnimationContainer
226- // If we have CheckboxOrRadioGroup.Label as a child, we render a screenreader-accessible validation message in the <legend>
227- aria-hidden = { Boolean ( labelChild ) }
228- show
229- >
230- { slots . validation }
231- </ ValidationAnimationContainer >
232- ) }
233- </ div >
234- </ CheckboxOrRadioGroupContext . Provider >
235- )
236- }
237-
23873 return (
23974 < CheckboxOrRadioGroupContext . Provider
24075 value = { {
@@ -245,43 +80,41 @@ const CheckboxOrRadioGroup: React.FC<React.PropsWithChildren<CheckboxOrRadioGrou
24580 } }
24681 >
24782 < div >
248- < Box
249- border = "none"
250- margin = { 0 }
251- mb = { validationChild ? 2 : undefined }
252- padding = { 0 }
83+ < BoxWithFallback
84+ className = { clsx ( className , classes . GroupFieldset ) }
85+ data-validation = { validationChild ? '' : undefined }
25386 { ...( labelChild
25487 ? {
25588 as : 'fieldset' ,
25689 disabled,
25790 }
25891 : { } ) }
259- className = { className }
26092 sx = { sx }
26193 >
26294 { labelChild ? (
26395 /*
264- Placing the caption text and validation text in the <legend> provides a better user
265- experience for more screenreaders.
96+ Placing the caption text and validation text in the <legend> provides a better user
97+ experience for more screenreaders.
26698
267- Reference: https://blog.tenon.io/accessible-validation-of-checkbox-and-radiobutton-groups/
268- */
269- < Box as = "legend" mb = { isLegendVisible ? 2 : undefined } padding = { 0 } >
99+ Reference: https://blog.tenon.io/accessible-validation-of-checkbox-and-radiobutton-groups/
100+ */
101+ < legend className = { classes . GroupLegend } data-legend-visible = { isLegendVisible ? '' : undefined } >
270102 { slots . label }
271103 { slots . caption }
272104 { React . isValidElement ( slots . validation ) && slots . validation . props . children && (
273105 < VisuallyHidden > { slots . validation . props . children } </ VisuallyHidden >
274106 ) }
275- </ Box >
107+ </ legend >
276108 ) : (
277109 /*
278- If CheckboxOrRadioGroup.Label wasn't passed as a child, we don't render a <legend>
279- but we still want to render a caption
280- */
110+ If CheckboxOrRadioGroup.Label wasn't passed as a child, we don't render a <legend>
111+ but we still want to render a caption
112+ */
281113 slots . caption
282114 ) }
283115
284- < Body
116+ < div
117+ className = { classes . Body }
285118 { ...( ! labelChild
286119 ? {
287120 [ 'aria-labelledby' ] : ariaLabelledby ,
@@ -292,8 +125,8 @@ const CheckboxOrRadioGroup: React.FC<React.PropsWithChildren<CheckboxOrRadioGrou
292125 : { } ) }
293126 >
294127 { React . Children . toArray ( rest ) . filter ( child => React . isValidElement ( child ) ) }
295- </ Body >
296- </ Box >
128+ </ div >
129+ </ BoxWithFallback >
297130 { validationChild && (
298131 < ValidationAnimationContainer
299132 // If we have CheckboxOrRadioGroup.Label as a child, we render a screenreader-accessible validation message in the <legend>
0 commit comments