diff --git a/.changeset/cool-snakes-bathe.md b/.changeset/dull-cheetahs-applaud.md
similarity index 55%
rename from .changeset/cool-snakes-bathe.md
rename to .changeset/dull-cheetahs-applaud.md
index 83896219e26..5a799c59928 100644
--- a/.changeset/cool-snakes-bathe.md
+++ b/.changeset/dull-cheetahs-applaud.md
@@ -2,4 +2,4 @@
"@primer/components": patch
---
-Migrate `Text` to TypeScript
+Migrate `Flash` to TypeScript
diff --git a/.changeset/happy-taxis-compare.md b/.changeset/eleven-days-hope.md
similarity index 52%
rename from .changeset/happy-taxis-compare.md
rename to .changeset/eleven-days-hope.md
index f7c15c5e33a..56c3ed395d0 100644
--- a/.changeset/happy-taxis-compare.md
+++ b/.changeset/eleven-days-hope.md
@@ -2,4 +2,4 @@
"@primer/components": patch
---
-Migrate `Flex` to TypeScript
+Migrate `Truncate` to TypeScript
diff --git a/.changeset/flat-moose-guess.md b/.changeset/flat-moose-guess.md
deleted file mode 100644
index a63cbd4b1f9..00000000000
--- a/.changeset/flat-moose-guess.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `BaseStyles` to TypeScript
diff --git a/.changeset/fluffy-peaches-study.md b/.changeset/fluffy-peaches-study.md
deleted file mode 100644
index f909526645f..00000000000
--- a/.changeset/fluffy-peaches-study.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `Heading` to TypeScript
diff --git a/.changeset/funny-kangaroos-worry.md b/.changeset/funny-kangaroos-worry.md
deleted file mode 100644
index 4d4dffd7d06..00000000000
--- a/.changeset/funny-kangaroos-worry.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `Label` to TypeScript
diff --git a/.changeset/funny-pots-explain.md b/.changeset/funny-pots-explain.md
new file mode 100644
index 00000000000..4791170c256
--- /dev/null
+++ b/.changeset/funny-pots-explain.md
@@ -0,0 +1,5 @@
+---
+"@primer/components": patch
+---
+
+Migrate `StyledOcticon` to TypeScript
diff --git a/.changeset/lovely-walls-cover.md b/.changeset/lovely-walls-cover.md
deleted file mode 100644
index 813c1f3f7ce..00000000000
--- a/.changeset/lovely-walls-cover.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `LabelGroup` to TypeScript
diff --git a/.changeset/mighty-pumpkins-behave.md b/.changeset/mighty-pumpkins-behave.md
deleted file mode 100644
index fd51936d82f..00000000000
--- a/.changeset/mighty-pumpkins-behave.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Add supported `htmlFor` prop to `FormGroupLabelProps` type definition
diff --git a/.changeset/nice-spies-compete.md b/.changeset/nice-spies-compete.md
deleted file mode 100644
index d11560bc33b..00000000000
--- a/.changeset/nice-spies-compete.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@primer/components': patch
----
-
-Migrate `BorderBox` to TypeScript
diff --git a/.changeset/sharp-pugs-tap.md b/.changeset/sharp-pugs-tap.md
deleted file mode 100644
index ec1ae8af2a3..00000000000
--- a/.changeset/sharp-pugs-tap.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `BranchName` to TypeScript
diff --git a/.changeset/slimy-rats-mix.md b/.changeset/slimy-rats-mix.md
deleted file mode 100644
index 81f5d0e0bfd..00000000000
--- a/.changeset/slimy-rats-mix.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `Pagehead` to TypeScript
diff --git a/.changeset/tricky-gifts-bake.md b/.changeset/tricky-gifts-bake.md
deleted file mode 100644
index c6e4fc812da..00000000000
--- a/.changeset/tricky-gifts-bake.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-"@primer/components": patch
----
-
-Migrate `Grid` to TypeScript
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000000..48fb6432522
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,48 @@
+# @primer/components
+
+## 23.0.2
+### Patch Changes
+
+
+
+- [`7128403c`](https://github.com/primer/components/commit/7128403c488a2cfefda3743d7f92be8142071bc8) [#979](https://github.com/primer/components/pull/979) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `Text` to TypeScript
+
+
+
+- [`fe16e21c`](https://github.com/primer/components/commit/fe16e21cb3a67d424cdbb663ea2d13e2397eb42c) [#982](https://github.com/primer/components/pull/982) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `BaseStyles` to TypeScript
+
+
+
+- [`ee806857`](https://github.com/primer/components/commit/ee8068579106d34309faa1a0c44e1ed25edafb59) [#975](https://github.com/primer/components/pull/975) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `Heading` to TypeScript
+
+
+
+- [`25315571`](https://github.com/primer/components/commit/2531557171cd2e39b980a456d42e15880e16256f) [#976](https://github.com/primer/components/pull/976) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `Label` to TypeScript
+
+
+
+- [`4076bf4e`](https://github.com/primer/components/commit/4076bf4e173d997c46ba1130c5f0f86f04952790) [#986](https://github.com/primer/components/pull/986) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `Flex` to TypeScript
+
+
+
+- [`397a46fe`](https://github.com/primer/components/commit/397a46fe1edee9c2bb71e6ceedafff8dc4e76cb2) [#976](https://github.com/primer/components/pull/976) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `LabelGroup` to TypeScript
+
+
+
+- [`e841e158`](https://github.com/primer/components/commit/e841e158dcc557169fce19c78d5d90af5fef6af6) [#983](https://github.com/primer/components/pull/983) Thanks [@shiftkey](https://github.com/shiftkey)! - Add supported `htmlFor` prop to `FormGroupLabelProps` type definition
+
+
+
+- [`dc0df4b2`](https://github.com/primer/components/commit/dc0df4b209d952b121f04fc86d0f2984a6e661cf) [#973](https://github.com/primer/components/pull/973) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `BorderBox` to TypeScript
+
+
+
+- [`0cac0042`](https://github.com/primer/components/commit/0cac00426d4d29c51d9f110f091aac06c49ec054) [#974](https://github.com/primer/components/pull/974) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `BranchName` to TypeScript
+
+
+
+- [`755a1a5c`](https://github.com/primer/components/commit/755a1a5c19f6d6298f9c6785b50fed71aaea59ad) [#977](https://github.com/primer/components/pull/977) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `Pagehead` to TypeScript
+
+
+
+- [`34ff4885`](https://github.com/primer/components/commit/34ff4885311686699fbb6d2e3fab0337bad3d016) [#989](https://github.com/primer/components/pull/989) Thanks [@colebemis](https://github.com/colebemis)! - Migrate `Grid` to TypeScript
diff --git a/contributor-docs/adrs/adr-001-typescript.md b/contributor-docs/adrs/adr-001-typescript.md
new file mode 100644
index 00000000000..da69c19d689
--- /dev/null
+++ b/contributor-docs/adrs/adr-001-typescript.md
@@ -0,0 +1,23 @@
+# ADR 1: TypeScript
+
+## Status
+
+Approved 2021-01-15
+
+## Context
+
+Primer React components was originally released without TypeScript type definitions, making it difficult for engineers to consume the library in TypeScript applications. In [July 2019](https://github.com/primer/components/commit/2983c935ea9ad600c04078adb25e40c3624c11fa#diff-7aa4473ede4abd9ec099e87fec67fd57afafaf39e05d493ab4533acc38547eb8), we created an [ambient declaration](https://www.geeksforgeeks.org/typescript-ambients-declaration/) file (`index.d.ts`) file to provide type definitions for TypeScript applications without having to rewrite Primer React components in TypeScript.
+
+`index.d.ts` has been an effective stopgap, enabling teams to build complex applications with Primer React components and TypeScript. However, because `index.d.ts` is disconnected from the implementation code, we've struggled to keep the type definitions up-to-date and accurate, as evidenced by [many](https://github.com/primer/components/issues/906) [TypeScript](https://github.com/primer/components/issues/540) [bug](https://github.com/primer/components/issues/520) [reports](https://github.com/primer/components/issues/534). As the library continues to grow in size and complexity, manually maintaining type definitions will become unsustainable.
+
+## Decision
+
+We will rewrite Primer React components in TypeScript.
+
+## Consequences
+
+- Type definitions can be generated by the TypeScript compiler, eliminating bugs caused by hand-written type definitions.
+- Engineers can upstream components from other TypeScript projects at GitHub without having to remove type annotations, improving the contributor experience.
+- We can refactor components with increased confidence.
+- Component prop documentation can be generated by [react-docgen-typescript](https://github.com/styleguidist/react-docgen-typescript), eliminating inaccurate and out-of-date hand-written prop documentation.
+- New contributors will need some familiarity with TypeScript in order to make code contributions.
diff --git a/package.json b/package.json
index 85cda9fb200..3bae654003a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@primer/components",
- "version": "23.0.1",
+ "version": "23.0.2",
"description": "Primer react components",
"main": "lib/index.js",
"module": "lib-esm/index.js",
diff --git a/src/Flash.js b/src/Flash.tsx
similarity index 67%
rename from src/Flash.js
rename to src/Flash.tsx
index fe741443ab7..da4c15d7428 100644
--- a/src/Flash.js
+++ b/src/Flash.tsx
@@ -1,24 +1,21 @@
import PropTypes from 'prop-types'
import styled from 'styled-components'
import {variant} from 'styled-system'
-import {COMMON, get} from './constants'
+import {COMMON, get, SystemCommonProps} from './constants'
import theme from './theme'
-import sx from './sx'
-
-const schemeMap = {
- red: 'danger',
- blue: 'default',
- yellow: 'warning',
- green: 'success'
-}
+import sx, {SxProp} from './sx'
const variants = variant({
scale: 'flash'
})
-const getIconColor = (variant, theme) => get(`flashIcon.${variant}`)(theme)
-
-const Flash = styled.div`
+const Flash = styled.div<
+ {
+ variant?: 'default' | 'warning' | 'success' | 'danger'
+ full?: boolean
+ } & SystemCommonProps &
+ SxProp
+>`
position: relative;
color: ${get('colors.text.grayDark')};
padding: ${get('space.3')};
@@ -32,12 +29,12 @@ const Flash = styled.div`
}
svg {
- color: ${props => getIconColor(props.variant, props.theme)};
+ color: ${props => get(`flashIcon.${props.variant}`)(props.theme)};
margin-right: ${get('space.2')};
}
${COMMON};
- ${variants}
+ ${variants};
${sx};
`
@@ -49,7 +46,6 @@ Flash.defaultProps = {
Flash.propTypes = {
children: PropTypes.node,
full: PropTypes.bool,
- scheme: PropTypes.oneOf(Object.keys(schemeMap)), // deprecate 20.0.0
variant: PropTypes.oneOf(['default', 'warning', 'success', 'danger']),
...COMMON.propTypes,
...sx.propTypes
diff --git a/src/StyledOcticon.js b/src/StyledOcticon.js
deleted file mode 100644
index 3138ddf69a7..00000000000
--- a/src/StyledOcticon.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import styled from 'styled-components'
-import {COMMON} from './constants'
-import theme from './theme'
-import sx from './sx'
-
-function IconWrapper({icon: IconComponent, className, ...rest}) {
- return
-}
-
-const StyledOcticon = styled(IconWrapper)`
- ${COMMON}
- ${sx}
-`
-
-StyledOcticon.defaultProps = {
- theme,
- size: 16
-}
-
-StyledOcticon.propTypes = {
- ...COMMON.propTypes,
- ...sx.propTypes,
- icon: PropTypes.elementType.isRequired,
- size: PropTypes.oneOfType([PropTypes.number, PropTypes.oneOf(['small', 'medium', 'large'])]),
- theme: PropTypes.object,
- verticalAlign: PropTypes.oneOf(['middle', 'text-bottom', 'text-top', 'top'])
-}
-
-export default StyledOcticon
diff --git a/src/StyledOcticon.tsx b/src/StyledOcticon.tsx
new file mode 100644
index 00000000000..36a4a2bd518
--- /dev/null
+++ b/src/StyledOcticon.tsx
@@ -0,0 +1,36 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import styled from 'styled-components'
+import {COMMON, SystemCommonProps} from './constants'
+import theme from './theme'
+import sx, {SxProp} from './sx'
+import {IconProps} from '@primer/octicons-react'
+import {ComponentProps} from './utils/types'
+
+type OcticonProps = {icon: React.ElementType} & IconProps
+
+function Octicon({icon: IconComponent, ...rest}: OcticonProps) {
+ return
+}
+
+const StyledOcticon = styled(Octicon)`
+ ${COMMON}
+ ${sx}
+`
+
+StyledOcticon.defaultProps = {
+ theme,
+ size: 16
+}
+
+StyledOcticon.propTypes = {
+ ...COMMON.propTypes,
+ ...sx.propTypes,
+ icon: PropTypes.any.isRequired,
+ size: PropTypes.any,
+ theme: PropTypes.object,
+ verticalAlign: PropTypes.oneOf(['middle', 'text-bottom', 'text-top', 'top'])
+}
+
+export type StyledOcticonProps = ComponentProps
+export default StyledOcticon
diff --git a/src/Truncate.js b/src/Truncate.tsx
similarity index 61%
rename from src/Truncate.js
rename to src/Truncate.tsx
index f817301a106..db07b254373 100644
--- a/src/Truncate.js
+++ b/src/Truncate.tsx
@@ -1,11 +1,21 @@
-import styled from 'styled-components'
-import {maxWidth} from 'styled-system'
import PropTypes from 'prop-types'
-import {TYPOGRAPHY, COMMON} from './constants'
+import styled from 'styled-components'
+import {maxWidth, MaxWidthProps} from 'styled-system'
+import {COMMON, SystemCommonProps, SystemTypographyProps, TYPOGRAPHY} from './constants'
+import sx, {SxProp} from './sx'
import theme from './theme'
-import sx from './sx'
+import {ComponentProps} from './utils/types'
+
+type StyledTruncateProps = {
+ title: string
+ inline?: boolean
+ expandable?: boolean
+} & MaxWidthProps &
+ SystemTypographyProps &
+ SystemCommonProps &
+ SxProp
-const Truncate = styled('div')`
+const Truncate = styled.div`
${TYPOGRAPHY}
${COMMON}
display: ${props => (props.inline ? 'inline-block' : 'inherit')};
@@ -19,7 +29,6 @@ const Truncate = styled('div')`
`
Truncate.defaultProps = {
- as: 'div',
expandable: false,
inline: false,
maxWidth: 125,
@@ -37,4 +46,5 @@ Truncate.propTypes = {
title: PropTypes.string.isRequired
}
+export type TruncateProps = ComponentProps
export default Truncate
diff --git a/src/__tests__/Flash.js b/src/__tests__/Flash.tsx
similarity index 100%
rename from src/__tests__/Flash.js
rename to src/__tests__/Flash.tsx
diff --git a/src/__tests__/StyledOcticon.js b/src/__tests__/StyledOcticon.tsx
similarity index 88%
rename from src/__tests__/StyledOcticon.js
rename to src/__tests__/StyledOcticon.tsx
index a29c4ffbdf9..fe63816ca21 100644
--- a/src/__tests__/StyledOcticon.js
+++ b/src/__tests__/StyledOcticon.tsx
@@ -15,10 +15,6 @@ describe('StyledOcticon', () => {
default: StyledOcticon
})
- it('implements system props', () => {
- expect(StyledOcticon).toImplementSystemProps(COMMON)
- })
-
it('should have no axe violations', async () => {
const {container} = HTMLRender()
const results = await axe(container)
diff --git a/src/__tests__/Truncate.js b/src/__tests__/Truncate.tsx
similarity index 100%
rename from src/__tests__/Truncate.js
rename to src/__tests__/Truncate.tsx
diff --git a/src/__tests__/__snapshots__/Flash.js.snap b/src/__tests__/__snapshots__/Flash.tsx.snap
similarity index 100%
rename from src/__tests__/__snapshots__/Flash.js.snap
rename to src/__tests__/__snapshots__/Flash.tsx.snap
diff --git a/src/__tests__/__snapshots__/StyledOcticon.js.snap b/src/__tests__/__snapshots__/StyledOcticon.tsx.snap
similarity index 100%
rename from src/__tests__/__snapshots__/StyledOcticon.js.snap
rename to src/__tests__/__snapshots__/StyledOcticon.tsx.snap
diff --git a/src/__tests__/__snapshots__/Truncate.js.snap b/src/__tests__/__snapshots__/Truncate.tsx.snap
similarity index 100%
rename from src/__tests__/__snapshots__/Truncate.js.snap
rename to src/__tests__/__snapshots__/Truncate.tsx.snap