From ab5860d760c95de91b5760c7feb9f4cb58ea9336 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Mon, 23 Aug 2021 14:26:37 +0200 Subject: [PATCH 1/8] convert to ts --- .eslintrc.js | 4 - package.json | 6 +- ...ts.stories.js => CodeSnippets.stories.tsx} | 0 .../{CodeSnippets.js => CodeSnippets.tsx} | 43 ++-- .../{Icon.stories.js => Icon.stories.tsx} | 6 +- .../{Input.stories.js => Input.stories.tsx} | 11 +- src/components/{Input.js => Input.tsx} | 193 +++++++++--------- ...nkTabs.stories.js => LinkTabs.stories.tsx} | 6 +- src/components/{LinkTabs.js => LinkTabs.tsx} | 29 +-- src/components/Radio.tsx | 1 - ...TA.stories.js => ShadowBoxCTA.stories.tsx} | 0 .../{ShadowBoxCTA.js => ShadowBoxCTA.tsx} | 26 +-- src/components/StoryLinkWrapper.js | 37 ---- src/components/StoryLinkWrapper.tsx | 30 +++ ...ding.stories.js => Subheading.stories.tsx} | 0 .../{Subheading.js => Subheading.tsx} | 4 +- ...xtarea.stories.js => Textarea.stories.tsx} | 1 + src/components/{Textarea.js => Textarea.tsx} | 93 ++++----- src/components/clipboard/Clipboard.tsx | 3 +- .../{Header.stories.js => Header.stories.tsx} | 0 src/components/header/NavLink.tsx | 6 +- .../{Modal.stories.js => Modal.stories.tsx} | 8 +- src/components/modal/{Modal.js => Modal.tsx} | 21 +- src/components/modal/WithModal.js | 52 ----- ...Modal.stories.js => WithModal.stories.tsx} | 19 +- src/components/modal/WithModal.tsx | 57 ++++++ ...stItem.stories.js => ListItem.stories.tsx} | 0 .../tooltip/{ListItem.js => ListItem.tsx} | 59 +++--- ...Tooltip.stories.js => Tooltip.stories.tsx} | 0 .../tooltip/{Tooltip.js => Tooltip.tsx} | 90 ++++---- src/components/tooltip/TooltipLinkList.js | 47 ----- ...stories.js => TooltipLinkList.stories.tsx} | 8 +- src/components/tooltip/TooltipLinkList.tsx | 33 +++ ....stories.js => TooltipMessage.stories.tsx} | 0 .../{TooltipMessage.js => TooltipMessage.tsx} | 32 ++- ...ote.stories.js => TooltipNote.stories.tsx} | 4 +- .../{TooltipNote.js => TooltipNote.tsx} | 16 +- ...tip.stories.js => WithTooltip.stories.tsx} | 11 +- .../{WithTooltip.js => WithTooltip.tsx} | 112 ++++------ src/{index.js => index.tsx} | 0 src/utils/{index.js => index.ts} | 0 ...rStorybook.js => loadFontsForStorybook.ts} | 0 yarn.lock | 12 ++ 43 files changed, 498 insertions(+), 582 deletions(-) rename src/components/{CodeSnippets.stories.js => CodeSnippets.stories.tsx} (100%) rename src/components/{CodeSnippets.js => CodeSnippets.tsx} (81%) rename src/components/{Icon.stories.js => Icon.stories.tsx} (89%) rename src/components/{Input.stories.js => Input.stories.tsx} (97%) rename src/components/{Input.js => Input.tsx} (73%) rename src/components/{LinkTabs.stories.js => LinkTabs.stories.tsx} (53%) rename src/components/{LinkTabs.js => LinkTabs.tsx} (78%) rename src/components/{ShadowBoxCTA.stories.js => ShadowBoxCTA.stories.tsx} (100%) rename src/components/{ShadowBoxCTA.js => ShadowBoxCTA.tsx} (79%) delete mode 100644 src/components/StoryLinkWrapper.js create mode 100644 src/components/StoryLinkWrapper.tsx rename src/components/{Subheading.stories.js => Subheading.stories.tsx} (100%) rename src/components/{Subheading.js => Subheading.tsx} (63%) rename src/components/{Textarea.stories.js => Textarea.stories.tsx} (99%) rename src/components/{Textarea.js => Textarea.tsx} (72%) rename src/components/header/{Header.stories.js => Header.stories.tsx} (100%) rename src/components/modal/{Modal.stories.js => Modal.stories.tsx} (97%) rename src/components/modal/{Modal.js => Modal.tsx} (85%) delete mode 100644 src/components/modal/WithModal.js rename src/components/modal/{WithModal.stories.js => WithModal.stories.tsx} (86%) create mode 100644 src/components/modal/WithModal.tsx rename src/components/tooltip/{ListItem.stories.js => ListItem.stories.tsx} (100%) rename src/components/tooltip/{ListItem.js => ListItem.tsx} (81%) rename src/components/tooltip/{Tooltip.stories.js => Tooltip.stories.tsx} (100%) rename src/components/tooltip/{Tooltip.js => Tooltip.tsx} (64%) delete mode 100644 src/components/tooltip/TooltipLinkList.js rename src/components/tooltip/{TooltipLinkList.stories.js => TooltipLinkList.stories.tsx} (79%) create mode 100644 src/components/tooltip/TooltipLinkList.tsx rename src/components/tooltip/{TooltipMessage.stories.js => TooltipMessage.stories.tsx} (100%) rename src/components/tooltip/{TooltipMessage.js => TooltipMessage.tsx} (69%) rename src/components/tooltip/{TooltipNote.stories.js => TooltipNote.stories.tsx} (81%) rename src/components/tooltip/{TooltipNote.js => TooltipNote.tsx} (70%) rename src/components/tooltip/{WithTooltip.stories.js => WithTooltip.stories.tsx} (94%) rename src/components/tooltip/{WithTooltip.js => WithTooltip.tsx} (65%) rename src/{index.js => index.tsx} (100%) rename src/utils/{index.js => index.ts} (100%) rename src/utils/{loadFontsForStorybook.js => loadFontsForStorybook.ts} (100%) diff --git a/.eslintrc.js b/.eslintrc.js index ebd98d0a..28d15eaf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,3 @@ -// const error = 2; -// const warn = 1; -const ignore = 0; - module.exports = { root: true, extends: ['@storybook/eslint-config-storybook'], diff --git a/package.json b/package.json index be40a6f6..5a19986e 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,14 @@ ], "scripts": { "build": "babel src -d dist --extensions \".js,.jsx,.ts,.tsx\" --ignore \"**/*.test.js\" --ignore \"**/*.stories.js\"", - "types": "tsc --declaration --emitDeclarationOnly --outDir dist --declarationMap", "build-docs": "build-storybook --docs", "build-storybook": "build-storybook -s .storybook/static", "lint": "yarn lint:js && yarn lint:package", "lint:js": "cross-env NODE_ENV=production eslint --cache --cache-location=.cache/eslint --ext .js,.jsx,.html,.ts,.tsx,.mjs --report-unused-disable-directives", "lint:package": "sort-package-json", "release": "dotenv yarn build & yarn types && auto shipit", - "storybook": "start-storybook -p 6006 -s .storybook/static" + "storybook": "start-storybook -p 6006 -s .storybook/static", + "types": "tsc --declaration --emitDeclarationOnly --outDir dist --declarationMap" }, "husky": { "hooks": { @@ -77,7 +77,9 @@ "@storybook/linter-config": "^2.5.0", "@storybook/react": "^6.2.0", "@types/fs-extra": "^9.0.1", + "@types/react-modal": "^3.12.1", "@types/styled-components": "^5.1.0", + "@types/uuid": "^8.3.1", "auto": "^9.50.1", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", diff --git a/src/components/CodeSnippets.stories.js b/src/components/CodeSnippets.stories.tsx similarity index 100% rename from src/components/CodeSnippets.stories.js rename to src/components/CodeSnippets.stories.tsx diff --git a/src/components/CodeSnippets.js b/src/components/CodeSnippets.tsx similarity index 81% rename from src/components/CodeSnippets.js rename to src/components/CodeSnippets.tsx index ca29fff6..d6a8b6bb 100644 --- a/src/components/CodeSnippets.js +++ b/src/components/CodeSnippets.tsx @@ -1,5 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; -import PropTypes from 'prop-types'; +import React, { ComponentProps, ComponentType, useRef, useState } from 'react'; import styled from 'styled-components'; import { Clipboard } from './clipboard/Clipboard'; @@ -53,9 +52,9 @@ const StyledClipboard = styled(Clipboard)` } `; -function Snippet({ snippet }) { +function Snippet({ snippet }: { snippet: SnippetType }) { const { PreSnippet: PreSnippetComponent, Snippet: SnippetComponent } = snippet; - const snippetRef = useRef(); + const snippetRef = useRef(); const getCopyContent = () => snippetRef.current && snippetRef.current.textContent; return ( @@ -71,13 +70,6 @@ function Snippet({ snippet }) { ); } -Snippet.propTypes = { - snippet: PropTypes.shape({ - Snippet: PropTypes.elementType.isRequired, - PreSnippet: PropTypes.elementType, - }).isRequired, -}; - const TabsWrapper = styled.div` background: ${color.lightest}; border-top-left-radius: ${spacing.borderRadius.small}px; @@ -97,7 +89,7 @@ const StyledTabs = styled(LinkTabs)` } `; -function SnippetList({ snippets }) { +function SnippetList({ snippets }: { snippets: SnippetType[] }) { const [activeSnippet, setActiveSnippet] = useState(snippets[0]); const tabItems = snippets.map((snippet, index) => { @@ -123,16 +115,10 @@ function SnippetList({ snippets }) { ); } -SnippetList.propTypes = { - snippets: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - renderTabLabel: PropTypes.func.isRequired, - }).isRequired - ).isRequired, -}; - -export function CodeSnippets({ snippets, ...rest }) { +export function CodeSnippets({ + snippets, + ...rest +}: Props & ComponentProps & { children?: never }) { return ( @@ -146,6 +132,13 @@ export function CodeSnippets({ snippets, ...rest }) { ); } -CodeSnippets.propTypes = { - snippets: PropTypes.arrayOf(PropTypes.shape({})).isRequired, -}; +interface SnippetType { + Snippet: ComponentType; + PreSnippet?: ComponentType; + id: string; + renderTabLabel: (...a: any[]) => string; +} + +interface Props { + snippets: SnippetType[]; +} diff --git a/src/components/Icon.stories.js b/src/components/Icon.stories.tsx similarity index 89% rename from src/components/Icon.stories.js rename to src/components/Icon.stories.tsx index ac1e3b68..c2c5762c 100644 --- a/src/components/Icon.stories.js +++ b/src/components/Icon.stories.tsx @@ -9,7 +9,7 @@ const Meta = styled.div` font-size: 12px; `; -const Item = styled.li` +const Item = styled.li<{ minimal?: boolean }>` display: inline-flex; flex-direction: row; align-items: center; @@ -62,7 +62,7 @@ export const Labels = () => ( {Object.keys(icons).map((key) => ( - + {key} ))} @@ -74,7 +74,7 @@ export const NoLabels = () => ( {Object.keys(icons).map((key) => ( - + ))} diff --git a/src/components/Input.stories.js b/src/components/Input.stories.tsx similarity index 97% rename from src/components/Input.stories.js rename to src/components/Input.stories.tsx index eb0c68fc..4bec6e67 100644 --- a/src/components/Input.stories.js +++ b/src/components/Input.stories.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import { action } from '@storybook/addon-actions'; import styled from 'styled-components'; @@ -148,17 +147,9 @@ const All = ({ appearance }) => ( ); -All.propTypes = { - appearance: PropTypes.string, -}; - -All.defaultProps = { - appearance: undefined, -}; - export const Default = () => ( - + ); diff --git a/src/components/Input.js b/src/components/Input.tsx similarity index 73% rename from src/components/Input.js rename to src/components/Input.tsx index 855d1d10..a1ef9c86 100644 --- a/src/components/Input.js +++ b/src/components/Input.tsx @@ -1,15 +1,24 @@ -import React, { useEffect, useCallback, useRef, useState, forwardRef } from 'react'; -import PropTypes from 'prop-types'; +import React, { + useEffect, + useCallback, + useRef, + useState, + forwardRef, + ReactNode, + FC, + ComponentProps, + MutableRefObject, +} from 'react'; import styled, { css } from 'styled-components'; import { color, typography, spacing } from './shared/styles'; import { jiggle } from './shared/animation'; import { Icon } from './Icon'; import { Link } from './Link'; -import WithTooltip, { validPlacements as validTooltipPlacements } from './tooltip/WithTooltip'; +import WithTooltip from './tooltip/WithTooltip'; import { TooltipMessage } from './tooltip/TooltipMessage'; // prettier-ignore -const Label = styled.label` +const Label = styled.label>` font-weight: ${props => props.appearance !== 'code' && typography.weight.bold}; font-family: ${props => props.appearance === 'code' && typography.type.code }; font-size: ${props => props.appearance === 'code' ? typography.size.s1 - 1 : typography.size.s2 }px; @@ -17,7 +26,7 @@ const Label = styled.label` `; // prettier-ignore -const LabelWrapper = styled.div` +const LabelWrapper = styled.div>` margin-bottom: 8px; ${props => props.hideLabel && css` @@ -55,7 +64,7 @@ const InputEl = styled.input` &:-webkit-autofill { -webkit-box-shadow: 0 0 0 3em ${color.lightest} inset; } `; -const getStackLevelStyling = (props) => { +const getStackLevelStyling = (props: Pick) => { const radius = 4; const stackLevelDefinedStyling = css` position: relative; @@ -97,7 +106,7 @@ const getStackLevelStyling = (props) => { }; // prettier-ignore -const InputWrapper = styled.div` +const InputWrapper = styled.div>` display: inline-block; position: relative; vertical-align: top; @@ -192,7 +201,7 @@ const InputWrapper = styled.div` `} `; // prettier-ignore -const InputContainer = styled.div` +const InputContainer = styled.div>` ${props => props.orientation === 'horizontal' && css` display: table-row; @@ -232,7 +241,11 @@ const Action = styled.div` z-index: 2; `; -const getErrorMessage = ({ error, value, lastErrorValue }) => { +const getErrorMessage = ({ + error, + value, + lastErrorValue, +}: Pick) => { let errorMessage = typeof error === 'function' ? error(value) : error; if (lastErrorValue) { if (value !== lastErrorValue) { @@ -242,25 +255,25 @@ const getErrorMessage = ({ error, value, lastErrorValue }) => { return errorMessage; }; -export const PureInput = forwardRef( +export const PureInput: FC> = forwardRef( ( { id, - value, + appearance = 'default', + className = null, + error = null, + errorTooltipPlacement = 'right', + hideLabel = false, + icon = null, label, - hideLabel, - orientation, - icon, - error, - appearance, - errorTooltipPlacement, - className, - lastErrorValue, - startingType, - type, - onActionClick, - stackLevel, - suppressErrorMessage, + lastErrorValue = null, + onActionClick = null, + orientation = 'vertical', + stackLevel = undefined, + startingType = 'text', + suppressErrorMessage = false, + type = 'text', + value = '', ...props }, ref @@ -339,84 +352,62 @@ export const PureInput = forwardRef( } ); -PureInput.propTypes = { - id: PropTypes.string.isRequired, - value: PropTypes.string, - appearance: PropTypes.oneOf(['default', 'pill', 'code']), - errorTooltipPlacement: PropTypes.oneOf(validTooltipPlacements), - stackLevel: PropTypes.oneOf(['top', 'middle', 'bottom']), - label: PropTypes.string.isRequired, - hideLabel: PropTypes.bool, - orientation: PropTypes.oneOf(['vertical', 'horizontal']), - icon: PropTypes.string, - error: PropTypes.oneOfType([PropTypes.node, PropTypes.func]), - suppressErrorMessage: PropTypes.bool, - className: PropTypes.string, - lastErrorValue: PropTypes.string, - startingType: PropTypes.string, - type: PropTypes.string, - onActionClick: PropTypes.func, -}; +interface Props { + id: string; + value?: string; + appearance?: 'default' | 'pill' | 'code' | 'tertiary'; + errorTooltipPlacement?: ComponentProps['placement']; + stackLevel?: 'top' | 'middle' | 'bottom'; + label: string; + hideLabel?: boolean; + orientation?: 'vertical' | 'horizontal'; + icon?: ComponentProps['icon']; + error?: ReactNode | Function; + suppressErrorMessage?: boolean; + className?: string; + lastErrorValue?: string; + startingType?: string; + type?: string; + onActionClick?: Function; +} + +export const Input = forwardRef>( + ({ type: startingType, startFocused, ...rest }, ref) => { + const [type, setType] = useState(startingType); + const togglePasswordType = useCallback( + (event) => { + // Make sure this does not submit a form + event.preventDefault(); + event.stopPropagation(); + if (type === 'password') { + setType('text'); + return; + } + setType('password'); + }, + [type, setType] + ); -PureInput.defaultProps = { - value: '', - appearance: 'default', - errorTooltipPlacement: 'right', - stackLevel: undefined, - hideLabel: false, - orientation: 'vertical', - icon: null, - error: null, - suppressErrorMessage: false, - className: null, - lastErrorValue: null, - startingType: 'text', - type: 'text', - onActionClick: null, -}; + // Outside refs take precedence + const selfRef = useRef(); + const inputRef = (ref as MutableRefObject) || selfRef; + const didFocusOnStart = useRef(false); -export const Input = forwardRef(({ type: startingType, startFocused, ...rest }, ref) => { - const [type, setType] = useState(startingType); - const togglePasswordType = useCallback( - (event) => { - // Make sure this does not submit a form - event.preventDefault(); - event.stopPropagation(); - if (type === 'password') { - setType('text'); - return; + useEffect(() => { + if (inputRef && inputRef.current && startFocused && !didFocusOnStart.current) { + inputRef.current.focus(); + didFocusOnStart.current = true; } - setType('password'); - }, - [type, setType] - ); - // Outside refs take precedence - const inputRef = ref || useRef(); - const didFocusOnStart = useRef(false); - useEffect(() => { - if (inputRef && inputRef.current && startFocused && !didFocusOnStart.current) { - inputRef.current.focus(); - didFocusOnStart.current = true; - } - }, [inputRef, inputRef.current, didFocusOnStart, didFocusOnStart.current]); - - return ( - - ); -}); - -Input.propTypes = { - startFocused: PropTypes.bool, - type: PropTypes.string, -}; + }, [inputRef, inputRef.current, didFocusOnStart, didFocusOnStart.current]); -Input.defaultProps = { - startFocused: false, - type: 'text', -}; + return ( + + ); + } +); diff --git a/src/components/LinkTabs.stories.js b/src/components/LinkTabs.stories.tsx similarity index 53% rename from src/components/LinkTabs.stories.js rename to src/components/LinkTabs.stories.tsx index 407ba7f0..d36e44fd 100644 --- a/src/components/LinkTabs.stories.js +++ b/src/components/LinkTabs.stories.tsx @@ -4,9 +4,9 @@ import React from 'react'; import { LinkTabs } from './LinkTabs'; const items = [ - { label: 'Activity', title: 'View activity', href: '/activity' }, - { label: 'Components', title: 'View components', href: '/components', isActive: true }, - { label: 'Changeset', title: 'View UI changes', href: '/changes' }, + { key: '1', label: 'Activity', title: 'View activity', href: '/activity' }, + { key: '2', label: 'Components', title: 'View components', href: '/components', isActive: true }, + { key: '3', label: 'Changeset', title: 'View UI changes', href: '/changes' }, ]; export default { diff --git a/src/components/LinkTabs.js b/src/components/LinkTabs.tsx similarity index 78% rename from src/components/LinkTabs.js rename to src/components/LinkTabs.tsx index 81a0c3e9..3fcb1d12 100644 --- a/src/components/LinkTabs.js +++ b/src/components/LinkTabs.tsx @@ -1,5 +1,4 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import React, { ComponentProps, FC } from 'react'; import styled, { css } from 'styled-components'; import { Link } from './Link'; @@ -53,7 +52,21 @@ const Tab = styled(Link)` `}; `; -export const LinkTabs = ({ isLoading, items, ...props }) => ( +type ItemProps = { + key: string; + label: string; +} & ComponentProps; + +interface Props { + isLoading?: boolean; + items: ItemProps[]; +} + +export const LinkTabs: FC> = ({ + isLoading = false, + items = [], + ...props +}) => ( {items.map(({ key, label, ...item }) => (
  • @@ -64,13 +77,3 @@ export const LinkTabs = ({ isLoading, items, ...props }) => ( ))} ); - -LinkTabs.propTypes = { - isLoading: PropTypes.bool, - items: PropTypes.arrayOf(PropTypes.object), -}; - -LinkTabs.defaultProps = { - isLoading: false, - items: [], -}; diff --git a/src/components/Radio.tsx b/src/components/Radio.tsx index 2fd49e37..393ee25e 100644 --- a/src/components/Radio.tsx +++ b/src/components/Radio.tsx @@ -1,5 +1,4 @@ import React, { ComponentProps, FunctionComponent, ReactNode } from 'react'; -import PropTypes from 'prop-types'; import styled, { css } from 'styled-components'; import { rgba } from 'polished'; import { color, typography } from './shared/styles'; diff --git a/src/components/ShadowBoxCTA.stories.js b/src/components/ShadowBoxCTA.stories.tsx similarity index 100% rename from src/components/ShadowBoxCTA.stories.js rename to src/components/ShadowBoxCTA.stories.tsx diff --git a/src/components/ShadowBoxCTA.js b/src/components/ShadowBoxCTA.tsx similarity index 79% rename from src/components/ShadowBoxCTA.js rename to src/components/ShadowBoxCTA.tsx index 3f97f28e..4fe83600 100644 --- a/src/components/ShadowBoxCTA.js +++ b/src/components/ShadowBoxCTA.tsx @@ -1,5 +1,4 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { ComponentProps, FC, ReactNode } from 'react'; import styled from 'styled-components'; import { breakpoint, spacing, typography } from './shared/styles'; @@ -56,7 +55,18 @@ const Action = styled.div` } `; -export const ShadowBoxCTA = ({ action, headingText, messageText, ...rest }) => ( +interface Props { + headingText: ReactNode; + messageText?: ReactNode; + action: ReactNode; +} + +export const ShadowBoxCTA: FC> = ({ + action, + headingText, + messageText, + ...rest +}) => ( {headingText} @@ -66,13 +76,3 @@ export const ShadowBoxCTA = ({ action, headingText, messageText, ...rest }) => ( {action} ); - -ShadowBoxCTA.propTypes = { - headingText: PropTypes.node.isRequired, - messageText: PropTypes.node, - action: PropTypes.node.isRequired, -}; - -ShadowBoxCTA.defaultProps = { - messageText: undefined, -}; diff --git a/src/components/StoryLinkWrapper.js b/src/components/StoryLinkWrapper.js deleted file mode 100644 index 65112fa2..00000000 --- a/src/components/StoryLinkWrapper.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -// This is allows us to test whether the link works via the actions addon -import React from 'react'; -import PropTypes from 'prop-types'; -import { action } from '@storybook/addon-actions'; - -const fireClickAction = action('onLinkClick'); - -export function StoryLinkWrapper({ children, className, href, onClick, to, ...rest }) { - const modifiedOnClick = (event) => { - event.preventDefault(); - onClick(); - fireClickAction(href || to); - }; - - return ( - - {children} - - ); -} - -StoryLinkWrapper.propTypes = { - // eslint-disable-next-line react/forbid-prop-types - children: PropTypes.any.isRequired, - className: PropTypes.string, - href: PropTypes.string, - onClick: PropTypes.func, - to: PropTypes.string, -}; - -StoryLinkWrapper.defaultProps = { - className: '', - href: null, - onClick: () => {}, - to: null, -}; diff --git a/src/components/StoryLinkWrapper.tsx b/src/components/StoryLinkWrapper.tsx new file mode 100644 index 00000000..d0f2114e --- /dev/null +++ b/src/components/StoryLinkWrapper.tsx @@ -0,0 +1,30 @@ +/* eslint-disable import/no-extraneous-dependencies */ +// This is allows us to test whether the link works via the actions addon +import React, { ComponentProps, FC } from 'react'; +import { action } from '@storybook/addon-actions'; + +const fireClickAction = action('onLinkClick'); + +export const StoryLinkWrapper: FC> = ({ + children, + href, + onClick, + to, + ...rest +}) => { + const modifiedOnClick: React.DOMAttributes['onClick'] = (event) => { + event.preventDefault(); + onClick(event); + fireClickAction(href || to); + }; + + return ( + + {children} + + ); +}; + +interface Props { + to: string; +} diff --git a/src/components/Subheading.stories.js b/src/components/Subheading.stories.tsx similarity index 100% rename from src/components/Subheading.stories.js rename to src/components/Subheading.stories.tsx diff --git a/src/components/Subheading.js b/src/components/Subheading.tsx similarity index 63% rename from src/components/Subheading.js rename to src/components/Subheading.tsx index 2dc6c124..8365b22d 100644 --- a/src/components/Subheading.js +++ b/src/components/Subheading.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { ComponentProps, FC } from 'react'; import styled from 'styled-components'; import { typography } from './shared/styles'; @@ -9,4 +9,4 @@ const Heading = styled.span` font-size: ${typography.size.s2 - 1}px; `; -export const Subheading = (props) => ; +export const Subheading: FC> = (props) => ; diff --git a/src/components/Textarea.stories.js b/src/components/Textarea.stories.tsx similarity index 99% rename from src/components/Textarea.stories.js rename to src/components/Textarea.stories.tsx index e236cd4e..67135f26 100644 --- a/src/components/Textarea.stories.js +++ b/src/components/Textarea.stories.tsx @@ -23,6 +23,7 @@ export const Default = () => (