diff --git a/.changeset/yellow-suits-smell.md b/.changeset/yellow-suits-smell.md new file mode 100644 index 00000000000..da805039978 --- /dev/null +++ b/.changeset/yellow-suits-smell.md @@ -0,0 +1,5 @@ +--- +"@primer/components": patch +--- + +Migrate `Header` to TypeScript diff --git a/src/Header.js b/src/Header.tsx similarity index 55% rename from src/Header.js rename to src/Header.tsx index e345a58ff03..669eb2cbc36 100644 --- a/src/Header.js +++ b/src/Header.tsx @@ -1,10 +1,19 @@ import styled, {css} from 'styled-components' import PropTypes from 'prop-types' import theme from './theme' -import {get, COMMON, TYPOGRAPHY, BORDER} from './constants' -import sx from './sx' +import {BORDER, COMMON, get, SystemCommonProps, SystemTypographyProps, SystemBorderProps, TYPOGRAPHY} from './constants' +import {ComponentProps} from './utils/types' +import sx, {SxProp} from './sx' +import * as History from 'history' -const Header = styled.div` +type StyledHeaderItemProps = {full?: boolean} & SystemCommonProps & SxProp +type StyledHeaderProps = SystemBorderProps & SystemCommonProps & SxProp +type StyledHeaderLinkProps = {to?: History.LocationDescriptor} & SystemCommonProps & + SxProp & + SystemTypographyProps & + SystemBorderProps + +const Header = styled.div` z-index: 32; display: flex; padding: ${get('space.3')}; @@ -19,16 +28,15 @@ const Header = styled.div` ${BORDER} ${sx}; ` - -Header.Item = styled.div` +const HeaderItem = styled.div` display: flex; margin-right: ${get('space.3')}; align-self: stretch; align-items: center; flex-wrap: nowrap; - ${props => - props.full && + ${({full}) => + full && css` flex: auto; `}; @@ -37,10 +45,11 @@ Header.Item = styled.div` ${BORDER}; ${sx}; ` -Header.Item.displayName = 'Header.Item' -Header.Link = styled.a.attrs(props => { - const isReactRouter = typeof props.to === 'string' +HeaderItem.displayName = 'Header.Item' + +const HeaderLink = styled.a.attrs(({to}) => { + const isReactRouter = typeof to === 'string' if (isReactRouter) { // according to their docs, NavLink supports aria-current: // https://reacttraining.com/react-router/web/api/NavLink/aria-current-string @@ -48,7 +57,7 @@ Header.Link = styled.a.attrs(props => { } else { return {} } -})` +})` font-weight: ${get('fontWeights.bold')}; color: ${get('colors.text.white')}; white-space: nowrap; @@ -67,7 +76,8 @@ Header.Link = styled.a.attrs(props => { ${TYPOGRAPHY}; ${sx}; ` -Header.Link.displayName = 'Header.Link' + +HeaderLink.displayName = 'Header.Link' Header.propTypes = { ...sx.propTypes, @@ -79,23 +89,18 @@ Header.defaultProps = { theme } -Header.Item.defaultProps = { - theme -} - -Header.Item.propTypes = { +HeaderItem.propTypes = { full: PropTypes.bool, ...COMMON.propTypes, ...BORDER.propTypes, ...sx.propTypes } -Header.Link.defaultProps = { +HeaderItem.defaultProps = { theme } -Header.Link.propTypes = { - as: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]), +HeaderLink.propTypes = { href: PropTypes.string, theme: PropTypes.object, ...COMMON.propTypes, @@ -104,4 +109,11 @@ Header.Link.propTypes = { ...sx.propTypes } -export default Header +HeaderLink.defaultProps = { + theme +} + +export type HeaderProps = ComponentProps +export type HeaderLinkProps = ComponentProps +export type HeaderItemProps = ComponentProps +export default Object.assign(Header, {Link: HeaderLink, Item: HeaderItem}) diff --git a/src/__tests__/Header.js b/src/__tests__/Header.tsx similarity index 100% rename from src/__tests__/Header.js rename to src/__tests__/Header.tsx diff --git a/src/__tests__/__snapshots__/Header.js.snap b/src/__tests__/__snapshots__/Header.tsx.snap similarity index 100% rename from src/__tests__/__snapshots__/Header.js.snap rename to src/__tests__/__snapshots__/Header.tsx.snap