diff --git a/.changeset/stupid-seals-explode.md b/.changeset/stupid-seals-explode.md
new file mode 100644
index 00000000000..cfd97c3a3d9
--- /dev/null
+++ b/.changeset/stupid-seals-explode.md
@@ -0,0 +1,5 @@
+---
+"@primer/components": patch
+---
+
+Migrate `TextInput` to TypeScript
diff --git a/@types/@styled-system/props/index.d.ts b/@types/@styled-system/props/index.d.ts
new file mode 100644
index 00000000000..d1bbf5dad03
--- /dev/null
+++ b/@types/@styled-system/props/index.d.ts
@@ -0,0 +1 @@
+declare module '@styled-system/props'
diff --git a/src/TextInput.js b/src/TextInput.tsx
similarity index 64%
rename from src/TextInput.js
rename to src/TextInput.tsx
index 1b7a682631a..104b8fd7cd1 100644
--- a/src/TextInput.js
+++ b/src/TextInput.tsx
@@ -4,10 +4,11 @@ import classnames from 'classnames'
import systemPropTypes from '@styled-system/prop-types'
import {omit, pick} from '@styled-system/props'
import styled, {css} from 'styled-components'
-import {variant, width, minWidth, maxWidth} from 'styled-system'
-import {COMMON, get} from './constants'
+import {variant, width, minWidth, maxWidth, MaxWidthProps, WidthProps, MinWidthProps} from 'styled-system'
+import {COMMON, get, SystemCommonProps} from './constants'
import theme from './theme'
-import sx from './sx'
+import sx, {SxProp} from './sx'
+import {ComponentProps} from './utils/types'
const sizeVariants = variant({
variants: {
@@ -26,28 +27,6 @@ const sizeVariants = variant({
}
})
-// using forwardRef is important so that other components (ex. SelectMenu) can autofocus the input
-const TextInput = React.forwardRef(({icon: IconComponent, className, block, disabled, sx, ...rest}, ref) => {
- // this class is necessary to style FilterSearch, plz no touchy!
- const wrapperClasses = classnames(className, 'TextInput-wrapper')
- const wrapperProps = pick(rest)
- const inputProps = omit(rest)
- return (
-
- {IconComponent && }
-
-
- )
-})
-
const Input = styled.input`
border: 0;
font-size: inherit;
@@ -60,7 +39,18 @@ const Input = styled.input`
}
`
-const Wrapper = styled.span`
+type StyledWrapperProps = {
+ disabled?: boolean
+ hasIcon?: boolean
+ block?: boolean
+ variant?: 'small' | 'large'
+} & SystemCommonProps &
+ WidthProps &
+ MinWidthProps &
+ MaxWidthProps &
+ SxProp
+
+const Wrapper = styled.span`
display: inline-flex;
align-items: stretch;
min-height: 34px;
@@ -126,6 +116,33 @@ const Wrapper = styled.span`
${sx};
`
+type TextInputInternalProps = {icon?: React.ComponentType<{className?: string}>} & ComponentProps &
+ ComponentProps
+
+// using forwardRef is important so that other components (ex. SelectMenu) can autofocus the input
+const TextInput = React.forwardRef(
+ ({icon: IconComponent, className, block, disabled, sx, ...rest}, ref) => {
+ // this class is necessary to style FilterSearch, plz no touchy!
+ const wrapperClasses = classnames(className, 'TextInput-wrapper')
+ const wrapperProps = pick(rest)
+ const inputProps = omit(rest)
+ return (
+
+ {IconComponent && }
+
+
+ )
+ }
+)
+
TextInput.defaultProps = {
theme,
type: 'text'
@@ -133,7 +150,7 @@ TextInput.defaultProps = {
TextInput.propTypes = {
block: PropTypes.bool,
- icon: PropTypes.elementType,
+ icon: PropTypes.any,
maxWidth: systemPropTypes.layout.maxWidth,
minWidth: systemPropTypes.layout.minWidth,
variant: PropTypes.oneOf(['small', 'large']),
@@ -144,4 +161,5 @@ TextInput.propTypes = {
TextInput.displayName = 'TextInput'
+export type TextInputProps = ComponentProps
export default TextInput
diff --git a/src/__tests__/TextInput.js b/src/__tests__/TextInput.tsx
similarity index 100%
rename from src/__tests__/TextInput.js
rename to src/__tests__/TextInput.tsx
diff --git a/src/__tests__/__snapshots__/TextInput.js.snap b/src/__tests__/__snapshots__/TextInput.tsx.snap
similarity index 100%
rename from src/__tests__/__snapshots__/TextInput.js.snap
rename to src/__tests__/__snapshots__/TextInput.tsx.snap