Skip to content

Commit da7debd

Browse files
authoredDec 13, 2024··
Revert #5370, #5349 due to visual regressions (#5434)
* Revert "refactor(FormControl): update to CSS Modules behind feature flag (#5370)" This reverts commit 204ded0. * Revert "refactor(Table): update to CSS Modules (#5349)" This reverts commit 2c79798. * Create healthy-eggs-pretend.md
1 parent 4bcf78b commit da7debd

16 files changed

+449
-1102
lines changed
 

‎.changeset/gentle-stingrays-search.md

-5
This file was deleted.

‎.changeset/healthy-eggs-pretend.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@primer/react": patch
3+
---
4+
5+
Revert "refactor(FormControl): update to CSS Modules behind feature flag" & "refactor(Table): update to CSS Modules"

‎.changeset/selfish-flowers-approve.md

-5
This file was deleted.

‎packages/react/src/DataTable/Table.module.css

-283
This file was deleted.

‎packages/react/src/DataTable/Table.tsx

+304-411
Large diffs are not rendered by default.

‎packages/react/src/FormControl/FormControl.module.css

-57
This file was deleted.

‎packages/react/src/FormControl/FormControl.tsx

+52-133
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {clsx} from 'clsx'
21
import React, {useContext} from 'react'
32
import Autocomplete from '../Autocomplete'
3+
import Box from '../Box'
44
import Checkbox from '../Checkbox'
55
import Radio from '../Radio'
66
import Select from '../Select/Select'
@@ -10,6 +10,7 @@ import TextInputWithTokens from '../TextInputWithTokens'
1010
import Textarea from '../Textarea'
1111
import {CheckboxOrRadioGroupContext} from '../internal/components/CheckboxOrRadioGroup'
1212
import ValidationAnimationContainer from '../internal/components/ValidationAnimationContainer'
13+
import {get} from '../constants'
1314
import {useSlots} from '../hooks/useSlots'
1415
import type {SxProp} from '../sx'
1516
import {useId} from '../hooks/useId'
@@ -19,12 +20,6 @@ import FormControlLeadingVisual from './FormControlLeadingVisual'
1920
import FormControlValidation from './_FormControlValidation'
2021
import {FormControlContextProvider} from './_FormControlContext'
2122
import {warning} from '../utils/warning'
22-
import styled from 'styled-components'
23-
import sx from '../sx'
24-
import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent'
25-
import {cssModulesFlag} from './feature-flags'
26-
import {useFeatureFlag} from '../FeatureFlags'
27-
import classes from './FormControl.module.css'
2823

2924
export type FormControlProps = {
3025
children?: React.ReactNode
@@ -50,7 +45,6 @@ export type FormControlProps = {
5045

5146
const FormControl = React.forwardRef<HTMLDivElement, FormControlProps>(
5247
({children, disabled: disabledProp, layout = 'vertical', id: idProp, required, sx, className}, ref) => {
53-
const enabled = useFeatureFlag(cssModulesFlag)
5448
const [slots, childrenWithoutSlots] = useSlots(children, {
5549
caption: FormControlCaption,
5650
label: FormControlLabel,
@@ -133,61 +127,69 @@ const FormControl = React.forwardRef<HTMLDivElement, FormControlProps>(
133127
}}
134128
>
135129
{isChoiceInput || layout === 'horizontal' ? (
136-
<StyledHorizontalLayout
130+
<Box
137131
ref={ref}
138-
data-has-leading-visual={slots.leadingVisual ? '' : undefined}
132+
display="flex"
133+
alignItems={slots.leadingVisual ? 'center' : undefined}
139134
sx={sx}
140-
className={clsx(className, {
141-
[classes.ControlHorizontalLayout]: enabled,
142-
})}
135+
className={className}
143136
>
144-
<StyledChoiceInputs className={classes.ControlChoiceInputs}>
145-
{React.isValidElement(InputComponent)
146-
? React.cloneElement(
147-
InputComponent as React.ReactElement<{
148-
id: string
149-
disabled: boolean
150-
required: boolean
151-
['aria-describedby']: string
152-
}>,
153-
{
154-
id,
155-
disabled,
156-
// allow checkboxes to be required
157-
required: required && !isRadioInput,
158-
['aria-describedby']: captionId as string,
159-
},
160-
)
161-
: null}
137+
<Box sx={{'> input': {marginLeft: 0, marginRight: 0}}}>
138+
{React.isValidElement(InputComponent) &&
139+
React.cloneElement(
140+
InputComponent as React.ReactElement<{
141+
id: string
142+
disabled: boolean
143+
required: boolean
144+
['aria-describedby']: string
145+
}>,
146+
{
147+
id,
148+
disabled,
149+
// allow checkboxes to be required
150+
required: required && !isRadioInput,
151+
['aria-describedby']: captionId as string,
152+
},
153+
)}
162154
{childrenWithoutSlots.filter(
163155
child =>
164156
React.isValidElement(child) &&
165157
![Checkbox, Radio].some(inputComponent => child.type === inputComponent),
166158
)}
167-
</StyledChoiceInputs>
168-
{slots.leadingVisual ? (
169-
<StyledLeadingVisual
170-
className={clsx({
171-
[classes.LeadingVisual]: enabled,
172-
})}
173-
data-disabled={disabled ? '' : undefined}
174-
data-has-caption={slots.caption ? '' : undefined}
159+
</Box>
160+
{slots.leadingVisual && (
161+
<Box
162+
color={disabled ? 'fg.muted' : 'fg.default'}
163+
sx={{
164+
'> *': {
165+
minWidth: slots.caption ? get('fontSizes.4') : get('fontSizes.2'),
166+
minHeight: slots.caption ? get('fontSizes.4') : get('fontSizes.2'),
167+
fill: 'currentColor',
168+
},
169+
}}
170+
ml={2}
175171
>
176172
{slots.leadingVisual}
177-
</StyledLeadingVisual>
178-
) : null}
179-
<StyledLabelContainer className={classes.LabelContainer}>
173+
</Box>
174+
)}
175+
<Box
176+
sx={{
177+
'> *': {paddingLeft: 'var(--stack-gap-condensed)'},
178+
'> label': {fontWeight: 'var(--base-text-weight-normal)'},
179+
}}
180+
>
180181
{slots.label}
181182
{slots.caption}
182-
</StyledLabelContainer>
183-
</StyledHorizontalLayout>
183+
</Box>
184+
</Box>
184185
) : (
185-
<StyledVerticalLayout
186+
<Box
186187
ref={ref}
187-
data-has-label={!isLabelHidden ? '' : undefined}
188-
className={clsx(className, {
189-
[classes.ControlVerticalLayout]: enabled,
190-
})}
188+
display="flex"
189+
flexDirection="column"
190+
alignItems="flex-start"
191+
sx={{...(isLabelHidden ? {'> *:not(label) + *': {marginTop: 1}} : {'> * + *': {marginTop: 1}}), ...sx}}
192+
className={className}
191193
>
192194
{slots.label}
193195
{React.isValidElement(InputComponent) &&
@@ -213,96 +215,13 @@ const FormControl = React.forwardRef<HTMLDivElement, FormControlProps>(
213215
<ValidationAnimationContainer show>{slots.validation}</ValidationAnimationContainer>
214216
) : null}
215217
{slots.caption}
216-
</StyledVerticalLayout>
218+
</Box>
217219
)}
218220
</FormControlContextProvider>
219221
)
220222
},
221223
)
222224

223-
const StyledHorizontalLayout = toggleStyledComponent(
224-
cssModulesFlag,
225-
'div',
226-
styled.div`
227-
display: flex;
228-
229-
&:where([data-has-leading-visual]) {
230-
align-items: center;
231-
}
232-
233-
${sx}
234-
`,
235-
)
236-
237-
const StyledChoiceInputs = toggleStyledComponent(
238-
cssModulesFlag,
239-
'div',
240-
styled.div`
241-
> input {
242-
margin-left: 0;
243-
margin-right: 0;
244-
}
245-
`,
246-
)
247-
248-
const StyledLabelContainer = toggleStyledComponent(
249-
cssModulesFlag,
250-
'div',
251-
styled.div`
252-
> * {
253-
padding-left: var(--stack-gap-condensed);
254-
}
255-
256-
> label {
257-
font-weight: var(--base-text-weight-normal);
258-
}
259-
`,
260-
)
261-
262-
const StyledVerticalLayout = toggleStyledComponent(
263-
cssModulesFlag,
264-
'div',
265-
styled.div`
266-
display: flex;
267-
flex-direction: column;
268-
align-items: flex-start;
269-
270-
& > *:not(label) + * {
271-
margin-top: var(--base-size-4);
272-
}
273-
274-
&:where([data-has-label]) > * + * {
275-
margin-top: var(--base-size-4);
276-
}
277-
278-
${sx}
279-
`,
280-
)
281-
282-
const StyledLeadingVisual = toggleStyledComponent(
283-
cssModulesFlag,
284-
'div',
285-
styled.div`
286-
color: var(--fgColor-default);
287-
margin-left: var(--base-size-8);
288-
289-
&:where([data-disabled]) {
290-
color: var(--fgColor-muted);
291-
}
292-
293-
> * {
294-
fill: currentColor;
295-
min-width: var(--text-body-size-large);
296-
min-height: var(--text-body-size-large);
297-
}
298-
299-
> *:where([data-has-caption]) {
300-
min-width: var(--base-size-24);
301-
min-height: var(--base-size-24);
302-
}
303-
`,
304-
)
305-
306225
export default Object.assign(FormControl, {
307226
Caption: FormControlCaption,
308227
Label: FormControlLabel,

‎packages/react/src/FormControl/FormControlCaption.module.css

-9
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
1-
import {clsx} from 'clsx'
21
import React from 'react'
3-
import styled from 'styled-components'
4-
import {cssModulesFlag} from './feature-flags'
5-
import {useFeatureFlag} from '../FeatureFlags'
6-
import Text from '../Text'
7-
import sx from '../sx'
82
import type {SxProp} from '../sx'
9-
import classes from './FormControlCaption.module.css'
103
import {useFormControlContext} from './_FormControlContext'
11-
import {toggleStyledComponent} from '../internal/utils/toggleStyledComponent'
4+
import Text from '../Text'
5+
import styled from 'styled-components'
6+
import {get} from '../constants'
7+
import sx from '../sx'
8+
9+
const StyledCaption = styled(Text)`
10+
color: var(--fgColor-muted);
11+
display: block;
12+
font-size: ${get('fontSizes.0')};
13+
14+
&:where([data-control-disabled]) {
15+
color: var(--control-fgColor-disabled);
16+
}
17+
18+
${sx}
19+
`
1220

1321
type FormControlCaptionProps = React.PropsWithChildren<
1422
{
@@ -17,36 +25,12 @@ type FormControlCaptionProps = React.PropsWithChildren<
1725
>
1826

1927
function FormControlCaption({id, children, sx}: FormControlCaptionProps) {
20-
const enabled = useFeatureFlag(cssModulesFlag)
2128
const {captionId, disabled} = useFormControlContext()
2229
return (
23-
<StyledCaption
24-
id={id ?? captionId}
25-
className={clsx({
26-
[classes.Caption]: enabled,
27-
})}
28-
data-control-disabled={disabled ? '' : undefined}
29-
sx={sx}
30-
>
30+
<StyledCaption id={id ?? captionId} data-control-disabled={disabled ? '' : undefined} sx={sx}>
3131
{children}
3232
</StyledCaption>
3333
)
3434
}
3535

36-
const StyledCaption = toggleStyledComponent(
37-
cssModulesFlag,
38-
Text,
39-
styled(Text)`
40-
color: var(--fgColor-muted);
41-
display: block;
42-
font-size: var(--text-body-size-small);
43-
44-
&:where([data-control-disabled]) {
45-
color: var(--control-fgColor-disabled);
46-
}
47-
48-
${sx}
49-
`,
50-
)
51-
5236
export {FormControlCaption}

‎packages/react/src/FormControl/__tests__/useFormControlForwardedProps.test.tsx

-53
This file was deleted.

‎packages/react/src/FormControl/feature-flags.ts

-1
This file was deleted.

‎packages/react/src/FormControl/__tests__/FormControl.test.tsx ‎packages/react/src/__tests__/FormControl.test.tsx

+53-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react'
22
import {render} from '@testing-library/react'
3+
import {renderHook} from '@testing-library/react-hooks'
34
import axe from 'axe-core'
45
import {
56
Autocomplete,
@@ -11,7 +12,8 @@ import {
1112
Textarea,
1213
TextInput,
1314
TextInputWithTokens,
14-
} from '../..'
15+
useFormControlForwardedProps,
16+
} from '..'
1517
import {MarkGithubIcon} from '@primer/octicons-react'
1618

1719
const LABEL_TEXT = 'Form control'
@@ -452,3 +454,53 @@ describe('FormControl', () => {
452454
})
453455
})
454456
})
457+
458+
describe('useFormControlForwardedProps', () => {
459+
describe('when used outside FormControl', () => {
460+
test('returns empty object when no props object passed', () => {
461+
const result = renderHook(() => useFormControlForwardedProps({}))
462+
expect(result.result.current).toEqual({})
463+
})
464+
465+
test('returns passed props object instance when passed', () => {
466+
const props = {id: 'test-id'}
467+
const result = renderHook(() => useFormControlForwardedProps(props))
468+
expect(result.result.current).toBe(props)
469+
})
470+
})
471+
472+
test('provides context value when no props object is passed', () => {
473+
const id = 'test-id'
474+
475+
const {result} = renderHook(() => useFormControlForwardedProps({}), {
476+
wrapper: ({children}: {children: React.ReactNode}) => (
477+
<FormControl id={id} disabled required>
478+
<FormControl.Label>Label</FormControl.Label>
479+
{children}
480+
</FormControl>
481+
),
482+
})
483+
484+
expect(result.current.disabled).toBe(true)
485+
expect(result.current.id).toBe(id)
486+
expect(result.current.required).toBe(true)
487+
})
488+
489+
test('merges with props object, overriding to prioritize props when conflicting', () => {
490+
const props = {id: 'override-id', xyz: 'someValue'}
491+
492+
const {result} = renderHook(() => useFormControlForwardedProps(props), {
493+
wrapper: ({children}: {children: React.ReactNode}) => (
494+
<FormControl id="form-control-id" disabled>
495+
<FormControl.Label>Label</FormControl.Label>
496+
{children}
497+
</FormControl>
498+
),
499+
})
500+
501+
expect(result.current.disabled).toBe(true)
502+
expect(result.current.id).toBe(props.id)
503+
expect(result.current.required).toBeFalsy()
504+
expect(result.current.xyz).toBe(props.xyz)
505+
})
506+
})

‎packages/react/src/internal/components/InputLabel.module.css

-32
This file was deleted.

‎packages/react/src/internal/components/InputLabel.tsx

+9-19
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
import {clsx} from 'clsx'
21
import React from 'react'
32
import styled from 'styled-components'
3+
import {get} from '../../constants'
44
import sx, {type SxProp} from '../../sx'
5-
import {cssModulesFlag} from '../../FormControl/feature-flags'
6-
import {useFeatureFlag} from '../../FeatureFlags'
7-
import classes from './InputLabel.module.css'
85

96
type BaseProps = SxProp & {
107
disabled?: boolean
@@ -42,26 +39,19 @@ function InputLabel({
4239
className,
4340
...props
4441
}: Props) {
45-
const enabled = useFeatureFlag(cssModulesFlag)
4642
return (
4743
<StyledLabel
4844
as={as}
4945
data-control-disabled={disabled ? '' : undefined}
5046
data-visually-hidden={visuallyHidden ? '' : undefined}
5147
htmlFor={htmlFor}
5248
id={id}
53-
className={clsx(className, {
54-
[classes.Label]: enabled,
55-
})}
49+
className={className}
5650
sx={sx}
5751
{...props}
5852
>
5953
{required || requiredText ? (
60-
<StyledRequiredText
61-
className={clsx({
62-
[classes.RequiredText]: enabled,
63-
})}
64-
>
54+
<StyledRequiredText>
6555
<span>{children}</span>
6656
<span aria-hidden={requiredIndicator ? undefined : true}>{requiredText ?? '*'}</span>
6757
</StyledRequiredText>
@@ -72,13 +62,18 @@ function InputLabel({
7262
)
7363
}
7464

65+
const StyledRequiredText = styled.span`
66+
display: flex;
67+
column-gap: ${get('space.1')};
68+
`
69+
7570
const StyledLabel = styled.label`
7671
align-self: flex-start;
7772
display: block;
7873
color: var(--fgColor-default);
7974
cursor: pointer;
8075
font-weight: 600;
81-
font-size: var(--text-body-size-medium);
76+
font-size: ${get('fontSizes.1')};
8277
8378
&:where([data-control-disabled]) {
8479
color: var(--fgColor-muted);
@@ -101,9 +96,4 @@ const StyledLabel = styled.label`
10196
${sx}
10297
`
10398

104-
const StyledRequiredText = styled.span`
105-
display: flex;
106-
column-gap: var(--base-size-4);
107-
`
108-
10999
export {InputLabel}

‎packages/react/src/internal/components/InputValidation.module.css

-32
This file was deleted.

‎packages/react/src/internal/components/InputValidation.tsx

+9-28
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import type {IconProps} from '@primer/octicons-react'
22
import {AlertFillIcon, CheckCircleFillIcon} from '@primer/octicons-react'
3-
import {clsx} from 'clsx'
43
import React from 'react'
5-
import styled from 'styled-components'
64
import Text from '../../Text'
7-
import sx from '../../sx'
85
import type {SxProp} from '../../sx'
9-
import {cssModulesFlag} from '../../FormControl/feature-flags'
106
import type {FormValidationStatus} from '../../utils/types/FormValidationStatus'
11-
import {useFeatureFlag} from '../../FeatureFlags'
12-
import classes from './InputValidation.module.css'
7+
import styled from 'styled-components'
8+
import {get} from '../../constants'
9+
import sx from '../../sx'
1310

1411
type Props = {
1512
id: string
@@ -25,7 +22,6 @@ const validationIconMap: Record<
2522
}
2623

2724
const InputValidation: React.FC<React.PropsWithChildren<Props>> = ({children, id, validationStatus, sx}) => {
28-
const enabled = useFeatureFlag(cssModulesFlag)
2925
const IconComponent = validationStatus ? validationIconMap[validationStatus] : undefined
3026

3127
// TODO: use `text-caption-lineHeight` token as a custom property when it's available
@@ -35,19 +31,10 @@ const InputValidation: React.FC<React.PropsWithChildren<Props>> = ({children, id
3531
const iconBoxMinHeight = iconSize * captionLineHeight
3632

3733
return (
38-
<StyledInputValidation
39-
className={clsx({
40-
[classes.InputValidation]: enabled,
41-
})}
42-
data-validation-status={validationStatus}
43-
sx={sx}
44-
>
34+
<StyledInputValidation data-validation-status={validationStatus} sx={sx}>
4535
{IconComponent ? (
4636
<StyledValidationIcon
4737
aria-hidden="true"
48-
className={clsx({
49-
[classes.ValidationIcon]: enabled,
50-
})}
5138
style={
5239
{
5340
'--inputValidation-iconSize': iconBoxMinHeight,
@@ -57,13 +44,7 @@ const InputValidation: React.FC<React.PropsWithChildren<Props>> = ({children, id
5744
<IconComponent size={iconSize} fill="currentColor" />
5845
</StyledValidationIcon>
5946
) : null}
60-
<StyledValidationText
61-
id={id}
62-
className={clsx({
63-
[classes.ValidationText]: enabled,
64-
})}
65-
style={{'--inputValidation-lineHeight': captionLineHeight} as React.CSSProperties}
66-
>
47+
<StyledValidationText id={id} style={{'--inputValidation-lineHeight': captionLineHeight} as React.CSSProperties}>
6748
{children}
6849
</StyledValidationText>
6950
</StyledInputValidation>
@@ -73,7 +54,7 @@ const InputValidation: React.FC<React.PropsWithChildren<Props>> = ({children, id
7354
const StyledInputValidation = styled(Text)`
7455
color: var(--inputValidation-fgColor);
7556
display: flex;
76-
font-size: var(--text-body-size-small);
57+
font-size: ${get('fontSizes.0')};
7758
font-weight: 600;
7859
7960
& :where(a) {
@@ -82,11 +63,11 @@ const StyledInputValidation = styled(Text)`
8263
}
8364
8465
&:where([data-validation-status='success']) {
85-
--inputValidation-fgColor: var(--fgColor-success);
66+
--inputValidation-fgColor: ${get('colors.success.fg')};
8667
}
8768
8869
&:where([data-validation-status='error']) {
89-
--inputValidation-fgColor: var(--fgColor-danger);
70+
--inputValidation-fgColor: ${get('colors.danger.fg')};
9071
}
9172
9273
${sx}
@@ -95,7 +76,7 @@ const StyledInputValidation = styled(Text)`
9576
const StyledValidationIcon = styled.span`
9677
align-items: center;
9778
display: flex;
98-
margin-inline-end: var(--base-size-4);
79+
margin-inline-end: ${get('space.1')};
9980
min-height: var(--inputValidation-iconSize);
10081
`
10182

0 commit comments

Comments
 (0)
Please sign in to comment.