From f94dcd33ffa20eb86ed685412c057b8df30d860d Mon Sep 17 00:00:00 2001 From: Mike Perrotti Date: Tue, 1 Mar 2022 08:14:57 -0500 Subject: [PATCH] Deprecate components replaced by FormControl (#1888) * moves InputField to deprecated package * adds jsdoc comments for deprecation * adds changeset * fixes bad autoformatting in changeset * fixes import path in test file * addresses PR feedback * fixes FormGroup import in test * addresses PR feedback * moves tests to depreacted directory * removes docs header image * fixes bad formatting in changelog markdown --- .changeset/olive-bears-act.md | 109 ++++++++++++++++++ docs/content/{ => deprecated}/FormGroup.md | 2 +- docs/content/{ => deprecated}/InputField.mdx | 16 +-- .../src/@primer/gatsby-theme-doctocat/nav.yml | 4 +- src/ChoiceInputField.tsx | 6 +- src/_ChoiceInputLeadingVisual.tsx | 2 +- src/__tests__/FormGroup.types.test.tsx | 2 +- .../{ => deprecated}/FormGroup.test.tsx | 6 +- .../{ => deprecated}/InputField.test.tsx | 3 +- .../__snapshots__/FormGroup.test.tsx.snap | 0 src/{ => deprecated}/FormGroup.tsx | 8 +- .../InputField/InputField.tsx | 11 +- .../InputField/_InputFieldCaption.tsx | 2 +- .../InputField/_InputFieldLabel.tsx | 2 +- .../InputField/_InputFieldValidation.tsx | 0 src/{ => deprecated}/InputField/index.ts | 0 src/{ => deprecated}/InputField/slots.ts | 2 +- src/deprecated/index.ts | 3 + src/index.ts | 3 - 19 files changed, 148 insertions(+), 33 deletions(-) create mode 100644 .changeset/olive-bears-act.md rename docs/content/{ => deprecated}/FormGroup.md (98%) rename docs/content/{ => deprecated}/InputField.mdx (96%) rename src/__tests__/{ => deprecated}/FormGroup.test.tsx (86%) rename src/__tests__/{ => deprecated}/InputField.test.tsx (98%) rename src/__tests__/{ => deprecated}/__snapshots__/FormGroup.test.tsx.snap (100%) rename src/{ => deprecated}/FormGroup.tsx (65%) rename src/{ => deprecated}/InputField/InputField.tsx (93%) rename src/{ => deprecated}/InputField/_InputFieldCaption.tsx (89%) rename src/{ => deprecated}/InputField/_InputFieldLabel.tsx (92%) rename src/{ => deprecated}/InputField/_InputFieldValidation.tsx (100%) rename src/{ => deprecated}/InputField/index.ts (100%) rename src/{ => deprecated}/InputField/slots.ts (63%) diff --git a/.changeset/olive-bears-act.md b/.changeset/olive-bears-act.md new file mode 100644 index 00000000000..9a56a789ba9 --- /dev/null +++ b/.changeset/olive-bears-act.md @@ -0,0 +1,109 @@ +--- +'@primer/react': major +--- + +The `FormControl` component will be used to deprecate the `FormGroup`, `InputField`, and `ChoiceInputField` components. It has the ability to render contextual content with your inputs: labels, validation statuses, captions. It also handles the ARIA attributes that make the form controls accessible to assistive technology. + + + + + + + + + + + + + +
Before After
+ +```jsx +import {FormControl, Checkbox, TextInput} from "@primer/react" + + + + Example text + + + +// OR + + + Example text + + + +// OR + + + Example text + + + +``` + + + +```jsx +import {FormGroup, TextInput} from "@primer/react" + + + Example text + + + +// OR + + + Example text + + + +``` + +
+ +```jsx +import {InputField} from '@primer/react' + + Example text + + +``` + + + +```jsx +import {FormControl} from '@primer/react' + + Example Text + + +``` + +
+ + + + + +
Migration steps to FormControl
+ +Upgrade to the new `FormControl` component by referring to the [examples in our documentation](https://primer.style/react/FormControl). + +or + +Continue using the deprecated `FormGroup`, `ChoiceInputField` or `InputField` : + +```js +import {FormGroup, ChoiceInputField, InputField} from '@primer/react/deprecated' // change your import statements +``` + +Codemods: + +- InputField codemod: https://github.com/primer/react-migrate/blob/main/src/use-deprecated-inputfield.js +- ChoiceInputField https://github.com/primer/react-migrate/blob/main/src/use-deprecated-choiceinputfield.js +- FormGroup codemod: https://github.com/primer/react-migrate/blob/main/src/use-deprecated-formgroup.js + +
diff --git a/docs/content/FormGroup.md b/docs/content/deprecated/FormGroup.md similarity index 98% rename from docs/content/FormGroup.md rename to docs/content/deprecated/FormGroup.md index 7ed49c395af..143c750db0e 100644 --- a/docs/content/FormGroup.md +++ b/docs/content/deprecated/FormGroup.md @@ -12,7 +12,7 @@ Use [FormControl](/FormControl) instead. ## Default example -```jsx live +```jsx live deprecated <> Example text diff --git a/docs/content/InputField.mdx b/docs/content/deprecated/InputField.mdx similarity index 96% rename from docs/content/InputField.mdx rename to docs/content/deprecated/InputField.mdx index d92ce7cbb91..6da7689f800 100644 --- a/docs/content/InputField.mdx +++ b/docs/content/deprecated/InputField.mdx @@ -7,7 +7,7 @@ source: https://github.com/primer/react/blob/main/src/InputField/InputField.tsx storybook: '/react/storybook?path=/story/forms-inputfield--text-input-field' --- -import {InputField, TextInputWithTokens, Autocomplete, Select} from '@primer/react' +import {TextInputWithTokens, Autocomplete, Select} from '@primer/react' ## Deprecation @@ -17,7 +17,7 @@ Use [FormControl](/FormControl) instead. ### Basic -```jsx live +```jsx live deprecated Name @@ -26,7 +26,7 @@ Use [FormControl](/FormControl) instead. ### Required -```jsx live +```jsx live deprecated Name @@ -35,7 +35,7 @@ Use [FormControl](/FormControl) instead. ### Disabled -```jsx live +```jsx live deprecated Name @@ -44,7 +44,7 @@ Use [FormControl](/FormControl) instead. ### Using different input components -```javascript live noinline +```javascript live noinline deprecated const TextInputWithTokensExample = () => { const [tokens, setTokens] = React.useState([ {text: 'zero', id: 0}, @@ -115,7 +115,7 @@ Every input must have a corresponding label to be accessible to assistive techno -```jsx live +```jsx live deprecated Name @@ -124,7 +124,7 @@ Every input must have a corresponding label to be accessible to assistive techno ### With a caption -```jsx live +```jsx live deprecated Name @@ -134,7 +134,7 @@ Every input must have a corresponding label to be accessible to assistive techno ### With validation -```javascript live noinline +```javascript live noinline deprecated const ValidationExample = () => { const [value, setValue] = React.useState('mona lisa') const [validationResult, setValidationResult] = React.useState() diff --git a/docs/src/@primer/gatsby-theme-doctocat/nav.yml b/docs/src/@primer/gatsby-theme-doctocat/nav.yml index 4d42a6e8cfe..13b7a3fe9b3 100644 --- a/docs/src/@primer/gatsby-theme-doctocat/nav.yml +++ b/docs/src/@primer/gatsby-theme-doctocat/nav.yml @@ -164,9 +164,11 @@ - title: Flex url: /deprecated/Flex - title: FormGroup - url: /FormGroup + url: /deprecated/FormGroup - title: Grid url: /deprecated/Grid + - title: InputField + url: /deprecated/InputField - title: Position url: /deprecated/Position - title: SelectMenu diff --git a/src/ChoiceInputField.tsx b/src/ChoiceInputField.tsx index dc329766fba..d3369e55550 100644 --- a/src/ChoiceInputField.tsx +++ b/src/ChoiceInputField.tsx @@ -1,11 +1,11 @@ import React from 'react' import {Box, Checkbox, Radio, useSSRSafeId} from '.' import {get} from './constants' -import {Slots} from './InputField/slots' +import {Slots} from './deprecated/InputField/slots' import ChoiceInputLeadingVisual from './_ChoiceInputLeadingVisual' -import InputField, {Props as InputFieldProps} from './InputField/InputField' +import InputField, {Props as InputFieldProps} from './deprecated/InputField/InputField' import {FormValidationStatus} from './utils/types/FormValidationStatus' -import InputFieldCaption from './InputField/_InputFieldCaption' +import InputFieldCaption from './deprecated/InputField/_InputFieldCaption' export interface Props extends Pick { /** diff --git a/src/_ChoiceInputLeadingVisual.tsx b/src/_ChoiceInputLeadingVisual.tsx index beecb6e32ea..912b70cf787 100644 --- a/src/_ChoiceInputLeadingVisual.tsx +++ b/src/_ChoiceInputLeadingVisual.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {Slot} from './InputField/slots' +import {Slot} from './deprecated/InputField/slots' const ChoiceInputLeadingVisual: React.FC = ({children}) => {children} diff --git a/src/__tests__/FormGroup.types.test.tsx b/src/__tests__/FormGroup.types.test.tsx index 5ed40fddaed..c35f16d3bd1 100644 --- a/src/__tests__/FormGroup.types.test.tsx +++ b/src/__tests__/FormGroup.types.test.tsx @@ -1,5 +1,5 @@ import React from 'react' -import FormGroup from '../FormGroup' +import FormGroup from '../deprecated/FormGroup' export function shouldAcceptCallWithNoProps() { return diff --git a/src/__tests__/FormGroup.test.tsx b/src/__tests__/deprecated/FormGroup.test.tsx similarity index 86% rename from src/__tests__/FormGroup.test.tsx rename to src/__tests__/deprecated/FormGroup.test.tsx index d9f5b5b223e..af68927a7b2 100644 --- a/src/__tests__/FormGroup.test.tsx +++ b/src/__tests__/deprecated/FormGroup.test.tsx @@ -1,6 +1,6 @@ import React from 'react' -import {FormGroup} from '..' -import {behavesAsComponent, checkExports} from '../utils/testing' +import FormGroup from '../../deprecated/FormGroup' +import {behavesAsComponent, checkExports} from '../../utils/testing' import {render as HTMLRender, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' import 'babel-polyfill' @@ -9,7 +9,7 @@ expect.extend(toHaveNoViolations) describe('FormGroup', () => { behavesAsComponent({Component: FormGroup}) - checkExports('FormGroup', { + checkExports('deprecated/FormGroup', { default: FormGroup }) diff --git a/src/__tests__/InputField.test.tsx b/src/__tests__/deprecated/InputField.test.tsx similarity index 98% rename from src/__tests__/InputField.test.tsx rename to src/__tests__/deprecated/InputField.test.tsx index 8cb06947a47..48ccec4443f 100644 --- a/src/__tests__/InputField.test.tsx +++ b/src/__tests__/deprecated/InputField.test.tsx @@ -2,7 +2,8 @@ import React from 'react' import {render, cleanup} from '@testing-library/react' import {axe, toHaveNoViolations} from 'jest-axe' import 'babel-polyfill' -import {Autocomplete, InputField, SSRProvider, TextInput, TextInputWithTokens} from '..' +import {Autocomplete, SSRProvider, TextInput, TextInputWithTokens} from '../../' +import InputField from '../../deprecated/InputField' expect.extend(toHaveNoViolations) const TEXTINPUTFIELD_LABEL_TEXT = 'Name' diff --git a/src/__tests__/__snapshots__/FormGroup.test.tsx.snap b/src/__tests__/deprecated/__snapshots__/FormGroup.test.tsx.snap similarity index 100% rename from src/__tests__/__snapshots__/FormGroup.test.tsx.snap rename to src/__tests__/deprecated/__snapshots__/FormGroup.test.tsx.snap diff --git a/src/FormGroup.tsx b/src/deprecated/FormGroup.tsx similarity index 65% rename from src/FormGroup.tsx rename to src/deprecated/FormGroup.tsx index 4ecd657a62a..83dfbfaacec 100644 --- a/src/FormGroup.tsx +++ b/src/deprecated/FormGroup.tsx @@ -1,7 +1,7 @@ import styled from 'styled-components' -import {get} from './constants' -import sx, {SxProp} from './sx' -import {ComponentProps} from './utils/types' +import {get} from '../constants' +import sx, {SxProp} from '../sx' +import {ComponentProps} from '../utils/types' const FormGroup = styled.div` margin: ${get('space.3')} 0; @@ -9,6 +9,7 @@ const FormGroup = styled.div` ${sx}; ` +/** @deprecated Use FormControl instead. See https://primer.style/react/FormControl for more details. */ const FormGroupLabel = styled.label` display: block; margin: 0 0 ${get('space.2')}; @@ -21,4 +22,5 @@ FormGroupLabel.displayName = 'FormGroup.Label' export type FormGroupProps = ComponentProps export type FormGroupLabelProps = ComponentProps +/** @deprecated Use FormControl instead. See https://primer.style/react/FormControl for more details. */ export default Object.assign(FormGroup, {Label: FormGroupLabel}) diff --git a/src/InputField/InputField.tsx b/src/deprecated/InputField/InputField.tsx similarity index 93% rename from src/InputField/InputField.tsx rename to src/deprecated/InputField/InputField.tsx index 32c780bfe2a..2aeb961d22b 100644 --- a/src/InputField/InputField.tsx +++ b/src/deprecated/InputField/InputField.tsx @@ -1,13 +1,13 @@ import React from 'react' -import {Autocomplete, Box, Select, TextInput, TextInputWithTokens, useSSRSafeId} from '..' -import InputValidation from '../_InputValidation' -import {ComponentProps} from '../utils/types' -import {FormValidationStatus} from '../utils/types/FormValidationStatus' +import {Autocomplete, Box, Select, TextInput, TextInputWithTokens, useSSRSafeId} from '../../' +import InputValidation from '../../_InputValidation' +import {ComponentProps} from '../../utils/types' +import {FormValidationStatus} from '../../utils/types/FormValidationStatus' import InputFieldCaption from './_InputFieldCaption' import InputFieldLabel from './_InputFieldLabel' import InputFieldValidation from './_InputFieldValidation' import {Slots} from './slots' -import ValidationAnimationContainer from '../_ValidationAnimationContainer' +import ValidationAnimationContainer from '../../_ValidationAnimationContainer' export interface Props> { children?: React.ReactNode /** @@ -40,6 +40,7 @@ export interface InputFieldContext validationMessageId: string } +/** @deprecated Use FormControl instead. See https://primer.style/react/FormControl for more details. */ const InputField = >({ children, disabled, diff --git a/src/InputField/_InputFieldCaption.tsx b/src/deprecated/InputField/_InputFieldCaption.tsx similarity index 89% rename from src/InputField/_InputFieldCaption.tsx rename to src/deprecated/InputField/_InputFieldCaption.tsx index 1a67ccc6e59..9e39a68de12 100644 --- a/src/InputField/_InputFieldCaption.tsx +++ b/src/deprecated/InputField/_InputFieldCaption.tsx @@ -1,5 +1,5 @@ import React from 'react' -import InputCaption from '../_InputCaption' +import InputCaption from '../../_InputCaption' import {InputFieldContext} from './InputField' import {Slot} from './slots' diff --git a/src/InputField/_InputFieldLabel.tsx b/src/deprecated/InputField/_InputFieldLabel.tsx similarity index 92% rename from src/InputField/_InputFieldLabel.tsx rename to src/deprecated/InputField/_InputFieldLabel.tsx index 10b27710226..843234da761 100644 --- a/src/InputField/_InputFieldLabel.tsx +++ b/src/deprecated/InputField/_InputFieldLabel.tsx @@ -1,5 +1,5 @@ import React from 'react' -import InputLabel from '../_InputLabel' +import InputLabel from '../../_InputLabel' import {InputFieldContext} from './InputField' import {Slot} from './slots' diff --git a/src/InputField/_InputFieldValidation.tsx b/src/deprecated/InputField/_InputFieldValidation.tsx similarity index 100% rename from src/InputField/_InputFieldValidation.tsx rename to src/deprecated/InputField/_InputFieldValidation.tsx diff --git a/src/InputField/index.ts b/src/deprecated/InputField/index.ts similarity index 100% rename from src/InputField/index.ts rename to src/deprecated/InputField/index.ts diff --git a/src/InputField/slots.ts b/src/deprecated/InputField/slots.ts similarity index 63% rename from src/InputField/slots.ts rename to src/deprecated/InputField/slots.ts index 1df9b0ed419..4418ab896c6 100644 --- a/src/InputField/slots.ts +++ b/src/deprecated/InputField/slots.ts @@ -1,3 +1,3 @@ -import createSlots from '../utils/create-slots' +import createSlots from '../../utils/create-slots' export const {Slots, Slot} = createSlots(['Caption', 'Input', 'Label', 'LeadingVisual']) diff --git a/src/deprecated/index.ts b/src/deprecated/index.ts index 269a38b4d9c..d1072fa209e 100644 --- a/src/deprecated/index.ts +++ b/src/deprecated/index.ts @@ -22,6 +22,9 @@ export type { DropdownItemProps, DropdownMenuProps } from '../Dropdown' +export {default as FormGroup} from './FormGroup' +export type {FormGroupProps, FormGroupLabelProps} from './FormGroup' +export {default as InputField} from './InputField' export {default as SelectMenu} from '../SelectMenu' export type { SelectMenuProps, diff --git a/src/index.ts b/src/index.ts index b41316a9a66..848c8fe5ad1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -79,13 +79,10 @@ export type {FilterListProps, FilterListItemProps} from './FilterList' export {default as Flash} from './Flash' export type {FlashProps} from './Flash' export {default as FormControl} from './FormControl' -export {default as FormGroup} from './FormGroup' -export type {FormGroupProps, FormGroupLabelProps} from './FormGroup' export {default as Header} from './Header' export type {HeaderProps, HeaderItemProps, HeaderLinkProps} from './Header' export {default as Heading} from './Heading' export type {HeadingProps} from './Heading' -export {default as InputField} from './InputField' export {default as LabelGroup} from './LabelGroup' export type {LabelGroupProps} from './LabelGroup' export {default as Label} from './Label'