diff --git a/src/components/guide-tooltip/GuideTooltip.stories.tsx b/src/components/guide-tooltip/GuideTooltip.stories.tsx index 580cc1f5f3..0f92162261 100644 --- a/src/components/guide-tooltip/GuideTooltip.stories.tsx +++ b/src/components/guide-tooltip/GuideTooltip.stories.tsx @@ -4,7 +4,7 @@ import GuideTooltip from './GuideTooltip'; import Button from '../button/Button'; import FolderShared32 from '../../icon/content/FolderShared32'; import notes from './GuideTooltip.stories.md'; -// @ts-ignore flow import +// @ts-ignore png import has no type declaration import testImageSrc from './test-image.png'; const addSpacing = (component: JSX.Element) =>
{component}
; diff --git a/src/components/guide-tooltip/GuideTooltip.tsx b/src/components/guide-tooltip/GuideTooltip.tsx index 9f6bc82955..4693a9e6ea 100644 --- a/src/components/guide-tooltip/GuideTooltip.tsx +++ b/src/components/guide-tooltip/GuideTooltip.tsx @@ -2,27 +2,30 @@ import * as React from 'react'; import { FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import Tooltip, { TooltipTheme } from '../tooltip'; +import Tooltip, { TooltipTheme, type TooltipProps } from '../tooltip'; import Button from '../button'; -// @ts-ignore flow import import messages from './messages'; import './GuideTooltip.scss'; -type TooltipProps = Omit, 'text' | 'theme'>; +type ButtonComponentProps = JSX.LibraryManagedAttributes; -type Props = TooltipProps & { +export interface GuideTooltipProps extends Omit { + /** Main content displayed in the guide tooltip body */ body: React.ReactNode; + /** Optional title displayed above the body */ title?: React.ReactNode; - /** 32px x 32px */ + /** Optional 32px x 32px icon displayed to the left of the content */ icon?: React.ReactNode; - /** A React component representing the image, cannot be used together with icon */ + /** Optional image content; cannot be used together with icon */ image?: React.ReactNode; - /** displays guide progress e.g. 1 of 4 */ + /** Displays guide progress, e.g. 1 of 4 */ steps?: [number, number]; - primaryButtonProps?: JSX.LibraryManagedAttributes; - secondaryButtonProps?: JSX.LibraryManagedAttributes; -}; + /** Props forwarded to the primary (next) Button */ + primaryButtonProps?: ButtonComponentProps; + /** Props forwarded to the secondary (previous) Button */ + secondaryButtonProps?: ButtonComponentProps; +} function GuideTooltip({ body, @@ -37,7 +40,7 @@ function GuideTooltip({ showCloseButton = true, title, ...rest -}: Props) { +}: GuideTooltipProps) { return ( { @@ -9,11 +8,11 @@ describe('components/guide-tooltip/GuideTooltip', () => { const body =
body
; const icon = ; const image = test; - const steps = [1, 3]; + const steps: [number, number] = [1, 3]; const primaryButtonProps = { children: 'Next' }; const secondaryButtonProps = { children: 'Previous' }; - const getWrapper = props => + const getWrapper = (props: Omit) => mount(
@@ -24,30 +23,30 @@ describe('components/guide-tooltip/GuideTooltip', () => { const wrapper = getWrapper({ body, title }); // hidden elements - expect(wrapper.find('.bdl-GuideTooltip-icon').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-image').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-previousButton').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-nextButton').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-steps').length).toEqual(0); + expect(wrapper.find('.bdl-GuideTooltip-icon')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-image')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-previousButton')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-nextButton')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-steps')).toHaveLength(0); // visible elements - expect(wrapper.find('.bdl-GuideTooltip-title').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-title').text()).toEqual('title'); - expect(wrapper.find('.bdl-GuideTooltip-body').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-body').text()).toEqual('body'); + expect(wrapper.find('.bdl-GuideTooltip-title')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-title').text()).toBe('title'); + expect(wrapper.find('.bdl-GuideTooltip-body')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-body').text()).toBe('body'); }); test('should render with just body', () => { const wrapper = getWrapper({ body }); // hidden elements - expect(wrapper.find('.bdl-GuideTooltip-title').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-icon').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-image').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-previousButton').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-nextButton').length).toEqual(0); - expect(wrapper.find('.bdl-GuideTooltip-steps').length).toEqual(0); + expect(wrapper.find('.bdl-GuideTooltip-title')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-icon')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-image')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-previousButton')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-nextButton')).toHaveLength(0); + expect(wrapper.find('.bdl-GuideTooltip-steps')).toHaveLength(0); // visible elements - expect(wrapper.find('.bdl-GuideTooltip-body').length).toEqual(1); + expect(wrapper.find('.bdl-GuideTooltip-body')).toHaveLength(1); expect(wrapper.find('.bdl-GuideTooltip-body').text()).toEqual('body'); }); @@ -55,31 +54,31 @@ describe('components/guide-tooltip/GuideTooltip', () => { const wrapper = getWrapper({ body, title, image, primaryButtonProps, secondaryButtonProps, steps }); // hidden elements - expect(wrapper.find('.bdl-GuideTooltip-icon').length).toEqual(0); + expect(wrapper.find('.bdl-GuideTooltip-icon')).toHaveLength(0); // visible elements - expect(wrapper.find('.bdl-GuideTooltip-title').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-title').text()).toEqual('title'); - expect(wrapper.find('.bdl-GuideTooltip-image img').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-body').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-body').text()).toEqual('body'); - expect(wrapper.find('Button.bdl-GuideTooltip-previousButton').length).toEqual(1); - expect(wrapper.find('Button.bdl-GuideTooltip-nextButton').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-steps').length).toEqual(1); + expect(wrapper.find('.bdl-GuideTooltip-title')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-title').text()).toBe('title'); + expect(wrapper.find('.bdl-GuideTooltip-image img')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-body')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-body').text()).toBe('body'); + expect(wrapper.find('Button.bdl-GuideTooltip-previousButton')).toHaveLength(1); + expect(wrapper.find('Button.bdl-GuideTooltip-nextButton')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-steps')).toHaveLength(1); }); test('should render with all options but image', () => { const wrapper = getWrapper({ body, title, icon, image, primaryButtonProps, secondaryButtonProps, steps }); // hidden elements - expect(wrapper.find('.bdl-GuideTooltip-image').length).toEqual(0); + expect(wrapper.find('.bdl-GuideTooltip-image')).toHaveLength(0); // visible elements - expect(wrapper.find('.bdl-GuideTooltip-title').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-title').text()).toEqual('title'); - expect(wrapper.find('.bdl-GuideTooltip-icon FolderShared32').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-body').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-body').text()).toEqual('body'); - expect(wrapper.find('Button.bdl-GuideTooltip-previousButton').length).toEqual(1); - expect(wrapper.find('Button.bdl-GuideTooltip-nextButton').length).toEqual(1); - expect(wrapper.find('.bdl-GuideTooltip-steps').length).toEqual(1); + expect(wrapper.find('.bdl-GuideTooltip-title')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-title').text()).toBe('title'); + expect(wrapper.find('.bdl-GuideTooltip-icon FolderShared32')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-body')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-body').text()).toBe('body'); + expect(wrapper.find('Button.bdl-GuideTooltip-previousButton')).toHaveLength(1); + expect(wrapper.find('Button.bdl-GuideTooltip-nextButton')).toHaveLength(1); + expect(wrapper.find('.bdl-GuideTooltip-steps')).toHaveLength(1); }); }); diff --git a/src/components/guide-tooltip/index.ts b/src/components/guide-tooltip/index.ts index 9f49f2f394..98eb294a42 100644 --- a/src/components/guide-tooltip/index.ts +++ b/src/components/guide-tooltip/index.ts @@ -1,2 +1,2 @@ -// @flow export { default } from './GuideTooltip'; +export type { GuideTooltipProps } from './GuideTooltip'; diff --git a/src/components/guide-tooltip/messages.js b/src/components/guide-tooltip/messages.js.flow similarity index 97% rename from src/components/guide-tooltip/messages.js rename to src/components/guide-tooltip/messages.js.flow index acee2d5ea4..aa40c3211a 100644 --- a/src/components/guide-tooltip/messages.js +++ b/src/components/guide-tooltip/messages.js.flow @@ -1,4 +1,3 @@ -// @flow import { defineMessages } from 'react-intl'; const messages = defineMessages({ diff --git a/src/components/guide-tooltip/messages.ts b/src/components/guide-tooltip/messages.ts new file mode 100644 index 0000000000..aa40c3211a --- /dev/null +++ b/src/components/guide-tooltip/messages.ts @@ -0,0 +1,11 @@ +import { defineMessages } from 'react-intl'; + +const messages = defineMessages({ + navigation: { + defaultMessage: '{currentStepIndex} of {totalNumSteps}', + description: 'Displays the navigation step index to the user of where they are in the guide. e.g. 1 of 4', + id: 'boxui.core.guidetooltip.navigation', + }, +}); + +export default messages;