From f86a9296995c81c1b59fd1c36d01026b60b033cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20=C4=8Curda?= Date: Fri, 15 Nov 2024 15:19:32 +0100 Subject: [PATCH] Fix(web-react): Mandatory href for anchors #DS-661 --- .../Breadcrumbs/BreadcrumbsItem.tsx | 1 + .../Breadcrumbs/demo/BreadcrumbsCustom.tsx | 6 ++- .../src/components/ButtonLink/ButtonLink.tsx | 4 +- .../ButtonLink/__tests__/ButtonLink.test.tsx | 16 +++++--- .../ButtonLink/demo/ButtonLinkDemoFactory.tsx | 6 +-- .../ButtonLink/stories/ButtonLink.stories.tsx | 1 + .../demo/CollapseMultipleTriggers.tsx | 2 +- .../CollapseVisibilityBreakpointDesktop.tsx | 2 +- .../CollapseVisibilityBreakpointTablet.tsx | 2 +- .../components/Footer/demo/FooterDefault.tsx | 10 ++--- .../components/Header/HeaderDialogLink.tsx | 7 ++-- .../src/components/Header/HeaderLink.tsx | 7 ++-- .../__tests__/HeaderDialogLink.test.tsx | 8 +++- .../Header/__tests__/HeaderLink.test.tsx | 8 +++- .../Header/demo/HeaderWithActions.tsx | 24 +++++++----- .../demo/HeaderWithActionsAndDialog.tsx | 39 ++++++++++--------- .../Header/stories/Header.stories.tsx | 38 +++++++++--------- .../stories/HeaderDesktopActions.stories.tsx | 38 +++++++++--------- .../Header/stories/HeaderDialog.stories.tsx | 38 +++++++++--------- .../stories/HeaderDialogActions.stories.tsx | 38 +++++++++--------- .../stories/HeaderDialogButton.stories.tsx | 38 +++++++++--------- .../HeaderDialogCloseButton.stories.tsx | 38 +++++++++--------- .../stories/HeaderDialogLink.stories.tsx | 36 ++++++++--------- .../stories/HeaderDialogNav.stories.tsx | 38 +++++++++--------- .../stories/HeaderDialogNavItem.stories.tsx | 38 +++++++++--------- .../stories/HeaderDialogText.stories.tsx | 38 +++++++++--------- .../Header/stories/HeaderLink.stories.tsx | 38 +++++++++--------- .../stories/HeaderMobileActions.stories.tsx | 38 +++++++++--------- .../Header/stories/HeaderNav.stories.tsx | 38 +++++++++--------- .../Header/stories/HeaderNavItem.stories.tsx | 38 +++++++++--------- .../web-react/src/components/Link/Link.tsx | 6 +-- .../components/Link/__tests__/Link.test.tsx | 4 +- .../Link/__tests__/useLinkStyleProps.test.ts | 2 +- .../src/components/Link/demo/LinkDefault.tsx | 4 +- .../src/components/Link/useLinkStyleProps.ts | 4 +- .../Pagination/PaginationButtonLink.tsx | 6 +-- .../components/Pagination/PaginationLink.tsx | 20 +++++++--- .../Pagination/PaginationLinkNext.tsx | 14 +++++-- .../Pagination/PaginationLinkPrevious.tsx | 16 +++++--- .../src/components/Pagination/README.md | 3 ++ .../Pagination/UncontrolledPagination.tsx | 4 ++ .../__tests__/PaginationLink.test.tsx | 4 +- .../__tests__/UncontrolledPagination.test.tsx | 24 ++++++++++-- .../web-react/src/components/Tabs/README.md | 1 + .../web-react/src/components/Tabs/TabLink.tsx | 6 +-- .../web-react/src/components/Toast/README.md | 2 +- .../src/components/Toast/ToastBarLink.tsx | 4 +- .../src/components/Toast/ToastContext.tsx | 9 ++++- packages/web-react/src/types/button.ts | 2 + packages/web-react/src/types/header.ts | 3 ++ packages/web-react/src/types/link.ts | 9 +++-- packages/web-react/src/types/pagination.ts | 10 +++-- packages/web-react/src/types/shared/index.ts | 1 + packages/web-react/src/types/shared/links.ts | 5 +++ packages/web-react/src/types/shared/refs.ts | 6 ++- packages/web-react/src/types/tabs.ts | 2 + packages/web-react/src/types/toast.ts | 12 +++--- 57 files changed, 496 insertions(+), 360 deletions(-) create mode 100644 packages/web-react/src/types/shared/links.ts diff --git a/packages/web-react/src/components/Breadcrumbs/BreadcrumbsItem.tsx b/packages/web-react/src/components/Breadcrumbs/BreadcrumbsItem.tsx index f3e3da7264..51a27119b8 100644 --- a/packages/web-react/src/components/Breadcrumbs/BreadcrumbsItem.tsx +++ b/packages/web-react/src/components/Breadcrumbs/BreadcrumbsItem.tsx @@ -9,6 +9,7 @@ import { Link } from '../Link'; import { useBreadcrumbsStyleProps } from './useBreadcrumbsStyleProps'; const defaultProps = { + href: '', iconNameEnd: 'chevron-right', iconNameStart: 'chevron-left', isCurrent: false, diff --git a/packages/web-react/src/components/Breadcrumbs/demo/BreadcrumbsCustom.tsx b/packages/web-react/src/components/Breadcrumbs/demo/BreadcrumbsCustom.tsx index 6bda316545..605560b8a4 100644 --- a/packages/web-react/src/components/Breadcrumbs/demo/BreadcrumbsCustom.tsx +++ b/packages/web-react/src/components/Breadcrumbs/demo/BreadcrumbsCustom.tsx @@ -1,4 +1,6 @@ import React, { Fragment } from 'react'; +import { ActionLinkColors } from '../../../constants'; +import { UNDERLINED_OPTIONS } from '../../../types'; import { Icon } from '../../Icon'; import { Link } from '../../Link'; import Breadcrumbs from '../Breadcrumbs'; @@ -29,9 +31,9 @@ const BreadcrumbsCustom = () => { const isLastItem = index === items.length - 1; const linkParams = { - underlined: isLastItem ? 'hover' : 'always', + underlined: isLastItem ? UNDERLINED_OPTIONS.HOVER : UNDERLINED_OPTIONS.ALWAYS, 'aria-current': isLastItem ? 'page' : undefined, - color: isLastItem ? 'secondary' : 'primary', + color: isLastItem ? ActionLinkColors.SECONDARY : ActionLinkColors.PRIMARY, }; return ( diff --git a/packages/web-react/src/components/ButtonLink/ButtonLink.tsx b/packages/web-react/src/components/ButtonLink/ButtonLink.tsx index f647eba7a3..8bc4c6523b 100644 --- a/packages/web-react/src/components/ButtonLink/ButtonLink.tsx +++ b/packages/web-react/src/components/ButtonLink/ButtonLink.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import React, { ElementType, ForwardedRef, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { SpiritButtonLinkProps } from '../../types'; +import { PolymorphicForwardRef, SpiritButtonLinkProps } from '../../types'; import { Spinner } from '../Spinner'; import { useButtonLinkAriaProps } from './useButtonLinkAriaProps'; import { useButtonLinkStyleProps } from './useButtonLinkStyleProps'; @@ -49,6 +49,6 @@ const _ButtonLink = ( ); }; -const ButtonLink = forwardRef>(_ButtonLink); +const ButtonLink = (forwardRef as PolymorphicForwardRef)(_ButtonLink); export default ButtonLink; diff --git a/packages/web-react/src/components/ButtonLink/__tests__/ButtonLink.test.tsx b/packages/web-react/src/components/ButtonLink/__tests__/ButtonLink.test.tsx index 9a25b44fd4..597d9f40a5 100644 --- a/packages/web-react/src/components/ButtonLink/__tests__/ButtonLink.test.tsx +++ b/packages/web-react/src/components/ButtonLink/__tests__/ButtonLink.test.tsx @@ -12,6 +12,10 @@ import { restPropsTest } from '../../../../tests/providerTests/restPropsTest'; import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest'; import ButtonLink from '../ButtonLink'; +const buttonLinkDefaultProps = { + href: '#', +}; + describe('ButtonLink', () => { classNamePrefixProviderTest(ButtonLink, 'Button'); @@ -28,14 +32,14 @@ describe('ButtonLink', () => { restPropsTest(ButtonLink, 'a'); it('should have default classname', () => { - const { container } = render(); + const { container } = render(); const element = container.querySelector('a') as HTMLElement; expect(element).toHaveClass('Button--primary'); }); it('should have disabled classname', () => { - const { container } = render(); + const { container } = render(); const element = container.querySelector('a') as HTMLElement; expect(element).toHaveClass('Button'); @@ -43,7 +47,7 @@ describe('ButtonLink', () => { }); it('should have block classname', () => { - const { container } = render(); + const { container } = render(); const element = container.querySelector('a') as HTMLElement; expect(element).toHaveClass('Button'); @@ -51,7 +55,7 @@ describe('ButtonLink', () => { }); it('should have size classname', () => { - const { container } = render(); + const { container } = render(); const element = container.querySelector('a') as HTMLElement; expect(element).toHaveClass('Button'); @@ -59,14 +63,14 @@ describe('ButtonLink', () => { }); it('should render text children', () => { - const dom = render(Hello World); + const dom = render(Hello World); const element = dom.container.querySelector('a') as HTMLElement; expect(element.textContent).toBe('Hello World'); }); it('should not have default type attribute', () => { - const { container } = render(); + const { container } = render(); const element = container.querySelector('a') as HTMLElement; expect(element).not.toHaveAttribute('type'); diff --git a/packages/web-react/src/components/ButtonLink/demo/ButtonLinkDemoFactory.tsx b/packages/web-react/src/components/ButtonLink/demo/ButtonLinkDemoFactory.tsx index b4c2245169..9dac6a18b8 100644 --- a/packages/web-react/src/components/ButtonLink/demo/ButtonLinkDemoFactory.tsx +++ b/packages/web-react/src/components/ButtonLink/demo/ButtonLinkDemoFactory.tsx @@ -17,14 +17,14 @@ const ButtonLinkDemoFactory = ({ ...props }: ButtonBaseProps) => { {colors.map((color) => (
- + {`Button ${color}`} {' '} - + Menu {' '} - +
diff --git a/packages/web-react/src/components/ButtonLink/stories/ButtonLink.stories.tsx b/packages/web-react/src/components/ButtonLink/stories/ButtonLink.stories.tsx index f26fec7a4c..510030c254 100644 --- a/packages/web-react/src/components/ButtonLink/stories/ButtonLink.stories.tsx +++ b/packages/web-react/src/components/ButtonLink/stories/ButtonLink.stories.tsx @@ -59,6 +59,7 @@ const meta: Meta = { args: { children: 'Click me', color: ActionButtonColors.PRIMARY, + href: '#', isBlock: false, isDisabled: false, isLoading: false, diff --git a/packages/web-react/src/components/Collapse/demo/CollapseMultipleTriggers.tsx b/packages/web-react/src/components/Collapse/demo/CollapseMultipleTriggers.tsx index 4fd536bdce..af25b772db 100644 --- a/packages/web-react/src/components/Collapse/demo/CollapseMultipleTriggers.tsx +++ b/packages/web-react/src/components/Collapse/demo/CollapseMultipleTriggers.tsx @@ -21,7 +21,7 @@ const CollapseMultipleTriggers = () => { {' '} - + Tertiary trigger diff --git a/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointDesktop.tsx b/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointDesktop.tsx index 0054026147..f66b0834db 100644 --- a/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointDesktop.tsx +++ b/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointDesktop.tsx @@ -8,7 +8,7 @@ const CollapseVisibilityBreakpointDesktop = () => { return ( <> - + Collapse trigger diff --git a/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointTablet.tsx b/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointTablet.tsx index a89c64f1c1..dfd7730c52 100644 --- a/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointTablet.tsx +++ b/packages/web-react/src/components/Collapse/demo/CollapseVisibilityBreakpointTablet.tsx @@ -8,7 +8,7 @@ const CollapseVisibilityBreakpointTablet = () => { return ( <> - + Collapse trigger diff --git a/packages/web-react/src/components/Footer/demo/FooterDefault.tsx b/packages/web-react/src/components/Footer/demo/FooterDefault.tsx index 12c2f5022f..be1d8dddc0 100644 --- a/packages/web-react/src/components/Footer/demo/FooterDefault.tsx +++ b/packages/web-react/src/components/Footer/demo/FooterDefault.tsx @@ -138,31 +138,31 @@ const FooterDefault = () => { {/* Flex with social media links */}
  • - + Facebook
  • - + X
  • - + YouTube
  • - + Google
  • - + LinkedIn diff --git a/packages/web-react/src/components/Header/HeaderDialogLink.tsx b/packages/web-react/src/components/Header/HeaderDialogLink.tsx index d1983af15d..6c6e98f308 100644 --- a/packages/web-react/src/components/Header/HeaderDialogLink.tsx +++ b/packages/web-react/src/components/Header/HeaderDialogLink.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import React, { ElementType, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { PolymorphicRef, SpiritDialogHeaderLinkProps } from '../../types'; +import { PolymorphicForwardRef, PolymorphicRef, SpiritDialogHeaderLinkProps } from '../../types'; import { useHeaderStyleProps } from './useHeaderStyleProps'; /* We need an exception for components exported with forwardRef */ @@ -12,7 +12,7 @@ const _HeaderDialogLink = ( props: SpiritDialogHeaderLinkProps, ref: PolymorphicRef, ): JSX.Element => { - const { elementType: ElementTag = 'a', children, isCurrent, ...restProps } = props; + const { elementType: ElementTag = 'a' as ElementType, children, isCurrent, ...restProps } = props; const { classProps } = useHeaderStyleProps({ isCurrentLink: isCurrent }); const { styleProps, props: otherProps } = useStyleProps(restProps); @@ -20,6 +20,7 @@ const _HeaderDialogLink = ( @@ -28,6 +29,6 @@ const _HeaderDialogLink = ( ); }; -const HeaderDialogLink = forwardRef>(_HeaderDialogLink); +const HeaderDialogLink = (forwardRef as PolymorphicForwardRef)(_HeaderDialogLink); export default HeaderDialogLink; diff --git a/packages/web-react/src/components/Header/HeaderLink.tsx b/packages/web-react/src/components/Header/HeaderLink.tsx index 08659799cb..09353327bf 100644 --- a/packages/web-react/src/components/Header/HeaderLink.tsx +++ b/packages/web-react/src/components/Header/HeaderLink.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import React, { ElementType, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { PolymorphicRef, SpiritHeaderLinkProps } from '../../types'; +import { PolymorphicForwardRef, PolymorphicRef, SpiritHeaderLinkProps } from '../../types'; import { useHeaderStyleProps } from './useHeaderStyleProps'; /* We need an exception for components exported with forwardRef */ @@ -12,7 +12,7 @@ const _HeaderLink = ( props: SpiritHeaderLinkProps, ref: PolymorphicRef, ): JSX.Element => { - const { elementType: ElementTag = 'a', children, isCurrent, ...restProps } = props; + const { elementType: ElementTag = 'a' as ElementType, children, isCurrent, ...restProps } = props; const { classProps } = useHeaderStyleProps({ isCurrentLink: isCurrent }); const { styleProps, props: otherProps } = useStyleProps(restProps); @@ -20,6 +20,7 @@ const _HeaderLink = ( @@ -28,6 +29,6 @@ const _HeaderLink = ( ); }; -const HeaderLink = forwardRef>(_HeaderLink); +const HeaderLink = (forwardRef as PolymorphicForwardRef)(_HeaderLink); export default HeaderLink; diff --git a/packages/web-react/src/components/Header/__tests__/HeaderDialogLink.test.tsx b/packages/web-react/src/components/Header/__tests__/HeaderDialogLink.test.tsx index b217c0b901..8b0d5c2c83 100644 --- a/packages/web-react/src/components/Header/__tests__/HeaderDialogLink.test.tsx +++ b/packages/web-react/src/components/Header/__tests__/HeaderDialogLink.test.tsx @@ -17,7 +17,11 @@ describe('HeaderDialogLink', () => { restPropsTest((props) => , 'a'); it('should render text children', () => { - const dom = render(Hello World); + const dom = render( + + Hello World + , + ); const element = dom.container.querySelector('a') as HTMLElement; expect(element.textContent).toBe('Hello World'); @@ -25,7 +29,7 @@ describe('HeaderDialogLink', () => { it('should render button element', () => { const dom = render( - + Hello World , ); diff --git a/packages/web-react/src/components/Header/__tests__/HeaderLink.test.tsx b/packages/web-react/src/components/Header/__tests__/HeaderLink.test.tsx index 627a7dcde6..fb43fd9ebc 100644 --- a/packages/web-react/src/components/Header/__tests__/HeaderLink.test.tsx +++ b/packages/web-react/src/components/Header/__tests__/HeaderLink.test.tsx @@ -14,7 +14,11 @@ describe('HeaderLink', () => { restPropsTest((props) => , 'a'); it('should render text children', () => { - const dom = render(Hello World); + const dom = render( + + Hello World + , + ); const element = dom.container.querySelector('a') as HTMLElement; expect(element.textContent).toBe('Hello World'); @@ -22,7 +26,7 @@ describe('HeaderLink', () => { it('should render button element', () => { const dom = render( - + Hello World , ); diff --git a/packages/web-react/src/components/Header/demo/HeaderWithActions.tsx b/packages/web-react/src/components/Header/demo/HeaderWithActions.tsx index 3a5c107560..eee16deb59 100644 --- a/packages/web-react/src/components/Header/demo/HeaderWithActions.tsx +++ b/packages/web-react/src/components/Header/demo/HeaderWithActions.tsx @@ -36,19 +36,21 @@ const HeaderWithActions = () => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -62,19 +64,21 @@ const HeaderWithActions = () => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers diff --git a/packages/web-react/src/components/Header/demo/HeaderWithActionsAndDialog.tsx b/packages/web-react/src/components/Header/demo/HeaderWithActionsAndDialog.tsx index 4cc5440332..d5457fd353 100644 --- a/packages/web-react/src/components/Header/demo/HeaderWithActionsAndDialog.tsx +++ b/packages/web-react/src/components/Header/demo/HeaderWithActionsAndDialog.tsx @@ -44,21 +44,21 @@ const HeaderWithActionsAndDialog = () => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -81,19 +81,21 @@ const HeaderWithActionsAndDialog = () => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -103,16 +105,17 @@ const HeaderWithActionsAndDialog = () => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Employers + Favourites - Notifications + Notifications Sign out @@ -130,16 +133,16 @@ const HeaderWithActionsAndDialog = () => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/Header.stories.tsx b/packages/web-react/src/components/Header/stories/Header.stories.tsx index 21a076eb8b..1d717ac9a9 100644 --- a/packages/web-react/src/components/Header/stories/Header.stories.tsx +++ b/packages/web-react/src/components/Header/stories/Header.stories.tsx @@ -77,21 +77,21 @@ const HeaderWithHooks = (args: HeaderProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -114,19 +114,21 @@ const HeaderWithHooks = (args: HeaderProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -136,16 +138,16 @@ const HeaderWithHooks = (args: HeaderProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -163,16 +165,16 @@ const HeaderWithHooks = (args: HeaderProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDesktopActions.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDesktopActions.stories.tsx index e9b82106b9..756a639040 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDesktopActions.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDesktopActions.stories.tsx @@ -67,21 +67,21 @@ const HeaderWithHooks = (args: HeaderDesktopActionsProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -104,19 +104,21 @@ const HeaderWithHooks = (args: HeaderDesktopActionsProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -126,16 +128,16 @@ const HeaderWithHooks = (args: HeaderDesktopActionsProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -153,16 +155,16 @@ const HeaderWithHooks = (args: HeaderDesktopActionsProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialog.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialog.stories.tsx index 05c614516b..ec75f20933 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialog.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialog.stories.tsx @@ -72,21 +72,21 @@ const HeaderWithHooks = (args: HeaderDialogProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -115,19 +115,21 @@ const HeaderWithHooks = (args: HeaderDialogProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -137,16 +139,16 @@ const HeaderWithHooks = (args: HeaderDialogProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -164,16 +166,16 @@ const HeaderWithHooks = (args: HeaderDialogProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogActions.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogActions.stories.tsx index 3ebdab2bfe..ea747ebabb 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogActions.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogActions.stories.tsx @@ -68,21 +68,21 @@ const HeaderWithHooks = (args: HeaderDialogActionsProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -105,19 +105,21 @@ const HeaderWithHooks = (args: HeaderDialogActionsProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -127,16 +129,16 @@ const HeaderWithHooks = (args: HeaderDialogActionsProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -154,16 +156,16 @@ const HeaderWithHooks = (args: HeaderDialogActionsProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogButton.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogButton.stories.tsx index 788da16faf..fd3daf57a1 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogButton.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogButton.stories.tsx @@ -58,21 +58,21 @@ const HeaderWithHooks = (args: HeaderDialogButtonProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -96,19 +96,21 @@ const HeaderWithHooks = (args: HeaderDialogButtonProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -118,16 +120,16 @@ const HeaderWithHooks = (args: HeaderDialogButtonProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -145,16 +147,16 @@ const HeaderWithHooks = (args: HeaderDialogButtonProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogCloseButton.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogCloseButton.stories.tsx index b4e396e4a3..4177027ec0 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogCloseButton.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogCloseButton.stories.tsx @@ -64,21 +64,21 @@ const HeaderWithHooks = (args: HeaderDialogCloseButtonProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -101,19 +101,21 @@ const HeaderWithHooks = (args: HeaderDialogCloseButtonProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -123,16 +125,16 @@ const HeaderWithHooks = (args: HeaderDialogCloseButtonProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -150,16 +152,16 @@ const HeaderWithHooks = (args: HeaderDialogCloseButtonProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogLink.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogLink.stories.tsx index 7a95684c21..28d1f97dfc 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogLink.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogLink.stories.tsx @@ -68,21 +68,21 @@ const HeaderWithHooks = (args: HeaderDialogLinkProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -105,19 +105,19 @@ const HeaderWithHooks = (args: HeaderDialogLinkProps) => { - + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -127,16 +127,16 @@ const HeaderWithHooks = (args: HeaderDialogLinkProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -154,16 +154,16 @@ const HeaderWithHooks = (args: HeaderDialogLinkProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogNav.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogNav.stories.tsx index 93c1f65843..5ad5070450 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogNav.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogNav.stories.tsx @@ -58,21 +58,21 @@ const HeaderWithHooks = (args: HeaderDialogNavProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -95,19 +95,21 @@ const HeaderWithHooks = (args: HeaderDialogNavProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -117,16 +119,16 @@ const HeaderWithHooks = (args: HeaderDialogNavProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -144,16 +146,16 @@ const HeaderWithHooks = (args: HeaderDialogNavProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogNavItem.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogNavItem.stories.tsx index 4216916527..e28023aa87 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogNavItem.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogNavItem.stories.tsx @@ -58,21 +58,21 @@ const HeaderWithHooks = (args: HeaderDialogNavItemProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -95,19 +95,21 @@ const HeaderWithHooks = (args: HeaderDialogNavItemProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -117,16 +119,16 @@ const HeaderWithHooks = (args: HeaderDialogNavItemProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -144,16 +146,16 @@ const HeaderWithHooks = (args: HeaderDialogNavItemProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderDialogText.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderDialogText.stories.tsx index 79b6e5431b..1b4d9488f3 100644 --- a/packages/web-react/src/components/Header/stories/HeaderDialogText.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderDialogText.stories.tsx @@ -62,21 +62,21 @@ const HeaderWithHooks = (args: HeaderDialogTextProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -99,19 +99,21 @@ const HeaderWithHooks = (args: HeaderDialogTextProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -121,16 +123,16 @@ const HeaderWithHooks = (args: HeaderDialogTextProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -148,16 +150,16 @@ const HeaderWithHooks = (args: HeaderDialogTextProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderLink.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderLink.stories.tsx index 31bb14b724..2c865272b5 100644 --- a/packages/web-react/src/components/Header/stories/HeaderLink.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderLink.stories.tsx @@ -68,19 +68,19 @@ const HeaderWithHooks = (args: HeaderLinkProps) => { - + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -103,19 +103,21 @@ const HeaderWithHooks = (args: HeaderLinkProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -125,16 +127,16 @@ const HeaderWithHooks = (args: HeaderLinkProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -152,16 +154,16 @@ const HeaderWithHooks = (args: HeaderLinkProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderMobileActions.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderMobileActions.stories.tsx index c48654fd4a..7f236896be 100644 --- a/packages/web-react/src/components/Header/stories/HeaderMobileActions.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderMobileActions.stories.tsx @@ -79,21 +79,21 @@ const HeaderWithHooks = (args: HeaderMobileActionsProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -116,19 +116,21 @@ const HeaderWithHooks = (args: HeaderMobileActionsProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -138,16 +140,16 @@ const HeaderWithHooks = (args: HeaderMobileActionsProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -165,16 +167,16 @@ const HeaderWithHooks = (args: HeaderMobileActionsProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderNav.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderNav.stories.tsx index 5951b313cd..07df74e62e 100644 --- a/packages/web-react/src/components/Header/stories/HeaderNav.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderNav.stories.tsx @@ -58,21 +58,21 @@ const HeaderWithHooks = (args: HeaderNavProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -95,19 +95,21 @@ const HeaderWithHooks = (args: HeaderNavProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -117,16 +119,16 @@ const HeaderWithHooks = (args: HeaderNavProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -144,16 +146,16 @@ const HeaderWithHooks = (args: HeaderNavProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Header/stories/HeaderNavItem.stories.tsx b/packages/web-react/src/components/Header/stories/HeaderNavItem.stories.tsx index f2c79a742c..05f68a9918 100644 --- a/packages/web-react/src/components/Header/stories/HeaderNavItem.stories.tsx +++ b/packages/web-react/src/components/Header/stories/HeaderNavItem.stories.tsx @@ -58,21 +58,21 @@ const HeaderWithHooks = (args: HeaderNavItemProps) => { - + Job offers - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -95,19 +95,21 @@ const HeaderWithHooks = (args: HeaderNavItemProps) => { - Job offers + + Job offers + - Part-time jobs + Part-time jobs - Inspiration + Inspiration - Replies + Replies - Employers + Employers @@ -117,16 +119,16 @@ const HeaderWithHooks = (args: HeaderNavItemProps) => { Marian - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out @@ -144,16 +146,16 @@ const HeaderWithHooks = (args: HeaderNavItemProps) => { - Dashboard + Dashboard - Profile + Profile - Favourites + Favourites - Notifications + Notifications Sign out diff --git a/packages/web-react/src/components/Link/Link.tsx b/packages/web-react/src/components/Link/Link.tsx index 21d22496f6..fbe7c394cf 100644 --- a/packages/web-react/src/components/Link/Link.tsx +++ b/packages/web-react/src/components/Link/Link.tsx @@ -3,10 +3,10 @@ import classNames from 'classnames'; import React, { ElementType, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { PolymorphicRef, SpiritLinkProps } from '../../types'; +import { PolymorphicForwardRef, PolymorphicRef, SpiritLinkProps } from '../../types'; import { useLinkStyleProps } from './useLinkStyleProps'; -const defaultProps: Partial = { +const defaultProps: Partial> = { elementType: 'a', color: 'primary', hasVisitedStyleAllowed: false, @@ -41,6 +41,6 @@ const _Link = ( ); }; -const Link = forwardRef>(_Link); +const Link = (forwardRef as PolymorphicForwardRef)(_Link); export default Link; diff --git a/packages/web-react/src/components/Link/__tests__/Link.test.tsx b/packages/web-react/src/components/Link/__tests__/Link.test.tsx index 031dca39e0..97ef7bb2a0 100644 --- a/packages/web-react/src/components/Link/__tests__/Link.test.tsx +++ b/packages/web-react/src/components/Link/__tests__/Link.test.tsx @@ -23,8 +23,8 @@ describe('Link', () => { } - underlined={underlined} - isDisabled={isDisabled} + underlined={underlined as string} + isDisabled={isDisabled as boolean} />, ); diff --git a/packages/web-react/src/components/Link/__tests__/useLinkStyleProps.test.ts b/packages/web-react/src/components/Link/__tests__/useLinkStyleProps.test.ts index 14dd585566..7b393ede64 100644 --- a/packages/web-react/src/components/Link/__tests__/useLinkStyleProps.test.ts +++ b/packages/web-react/src/components/Link/__tests__/useLinkStyleProps.test.ts @@ -26,7 +26,7 @@ describe('useLinkStyleProps', () => { }); it('should return link-allowed-visited class', () => { - const props = { color: 'primary', hasVisitedStyleAllowed: true } as SpiritLinkProps; + const props = { href: '#', color: 'primary', hasVisitedStyleAllowed: true } as SpiritLinkProps; const { result } = renderHook(() => useLinkStyleProps(props)); expect(result.current.classProps).toContain('link-allow-visited-style'); diff --git a/packages/web-react/src/components/Link/demo/LinkDefault.tsx b/packages/web-react/src/components/Link/demo/LinkDefault.tsx index 1433797e26..35703c82c6 100644 --- a/packages/web-react/src/components/Link/demo/LinkDefault.tsx +++ b/packages/web-react/src/components/Link/demo/LinkDefault.tsx @@ -3,11 +3,13 @@ import Link from '../Link'; const LinkDefault = () => ( <> - Link + Link ⚠️ Link with Icon + + Button ); diff --git a/packages/web-react/src/components/Link/useLinkStyleProps.ts b/packages/web-react/src/components/Link/useLinkStyleProps.ts index 95d76d9763..fbfd2c722c 100644 --- a/packages/web-react/src/components/Link/useLinkStyleProps.ts +++ b/packages/web-react/src/components/Link/useLinkStyleProps.ts @@ -10,7 +10,9 @@ export interface LinkStyles { props: Partial>; } -export function useLinkStyleProps(props: SpiritLinkProps): LinkStyles { +export function useLinkStyleProps( + props: Partial>, +): LinkStyles { const { color, hasVisitedStyleAllowed, isDisabled, underlined, ...restProps } = props; const linkClass = useClassNamePrefix('link'); diff --git a/packages/web-react/src/components/Pagination/PaginationButtonLink.tsx b/packages/web-react/src/components/Pagination/PaginationButtonLink.tsx index eb20fb51a1..628537c467 100644 --- a/packages/web-react/src/components/Pagination/PaginationButtonLink.tsx +++ b/packages/web-react/src/components/Pagination/PaginationButtonLink.tsx @@ -1,7 +1,7 @@ 'use client'; import React, { ElementType, ForwardedRef, forwardRef } from 'react'; -import { SpiritPaginationButtonLinkProps } from '../../types'; +import { PolymorphicForwardRef, SpiritPaginationButtonLinkProps } from '../../types'; import { ButtonLink } from '../Button'; import { Icon } from '../Icon'; import { VisuallyHidden } from '../VisuallyHidden'; @@ -20,13 +20,13 @@ const _PaginationButtonLink = ( }; return ( - + {accessibilityLabel} ); }; -const PaginationButtonLink = forwardRef(_PaginationButtonLink); +const PaginationButtonLink = (forwardRef as PolymorphicForwardRef)(_PaginationButtonLink); export default PaginationButtonLink; diff --git a/packages/web-react/src/components/Pagination/PaginationLink.tsx b/packages/web-react/src/components/Pagination/PaginationLink.tsx index 10c8080c45..b85f3862a2 100644 --- a/packages/web-react/src/components/Pagination/PaginationLink.tsx +++ b/packages/web-react/src/components/Pagination/PaginationLink.tsx @@ -1,16 +1,25 @@ 'use client'; import classNames from 'classnames'; -import React, { ElementType, forwardRef } from 'react'; +import React, { ElementType, ForwardedRef, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { PolymorphicRef, SpiritPaginationLinkProps } from '../../types'; +import { PolymorphicForwardRef, SpiritPaginationLinkProps } from '../../types'; import { VisuallyHidden } from '../VisuallyHidden'; import { usePaginationStyleProps } from './usePaginationStyleProps'; /* We need an exception for components exported with forwardRef */ /* eslint no-underscore-dangle: ['error', { allow: ['_PaginationLink'] }] */ -const _PaginationLink = (props: SpiritPaginationLinkProps, ref: PolymorphicRef) => { - const { elementType: ElementTag = 'a', accessibilityLabel, isCurrent, pageNumber, ...restProps } = props; +const _PaginationLink = ( + props: SpiritPaginationLinkProps, + ref: ForwardedRef, +) => { + const { + elementType: ElementTag = 'a' as ElementType, + accessibilityLabel, + isCurrent, + pageNumber, + ...restProps + } = props; const { classProps } = usePaginationStyleProps({ isCurrent }); const { styleProps, props: transferProps } = useStyleProps(restProps); @@ -20,6 +29,7 @@ const _PaginationLink = (props: SpiritPaginationLin ref={ref} {...transferProps} {...styleProps} + href={restProps.href} className={classNames(classProps.link, styleProps.className)} > {accessibilityLabel} @@ -28,6 +38,6 @@ const _PaginationLink = (props: SpiritPaginationLin ); }; -const PaginationLink = forwardRef(_PaginationLink); +const PaginationLink = (forwardRef as PolymorphicForwardRef)(_PaginationLink); export default PaginationLink; diff --git a/packages/web-react/src/components/Pagination/PaginationLinkNext.tsx b/packages/web-react/src/components/Pagination/PaginationLinkNext.tsx index a2d78dc756..13efd16b97 100644 --- a/packages/web-react/src/components/Pagination/PaginationLinkNext.tsx +++ b/packages/web-react/src/components/Pagination/PaginationLinkNext.tsx @@ -1,7 +1,7 @@ 'use client'; import React, { ElementType, ForwardedRef, forwardRef } from 'react'; -import { SpiritPaginationLinkPreviousNextProps } from '../../types'; +import { PolymorphicForwardRef, SpiritPaginationLinkPreviousNextProps } from '../../types'; import { PAGINATION_NEXT_LINK_DEFAULT_ACCESSIBILITY_LABEL } from './constants'; import PaginationButtonLink from './PaginationButtonLink'; @@ -13,8 +13,16 @@ const _PaginationLinkNext = ( ...restProps }: SpiritPaginationLinkPreviousNextProps, ref: ForwardedRef, -) => ; +) => ( + +); -const PaginationLinkNext = forwardRef(_PaginationLinkNext); +const PaginationLinkNext = (forwardRef as PolymorphicForwardRef)(_PaginationLinkNext); export default PaginationLinkNext; diff --git a/packages/web-react/src/components/Pagination/PaginationLinkPrevious.tsx b/packages/web-react/src/components/Pagination/PaginationLinkPrevious.tsx index 1fecce44ad..6217704275 100644 --- a/packages/web-react/src/components/Pagination/PaginationLinkPrevious.tsx +++ b/packages/web-react/src/components/Pagination/PaginationLinkPrevious.tsx @@ -1,7 +1,7 @@ 'use client'; import React, { ElementType, ForwardedRef, forwardRef } from 'react'; -import { SpiritPaginationLinkPreviousNextProps } from '../../types'; +import { PolymorphicForwardRef, SpiritPaginationLinkPreviousNextProps } from '../../types'; import { PAGINATION_PREVIOUS_LINK_DEFAULT_ACCESSIBILITY_LABEL } from './constants'; import PaginationButtonLink from './PaginationButtonLink'; @@ -13,10 +13,16 @@ const _PaginationLinkPrevious = ( ...restProps }: SpiritPaginationLinkPreviousNextProps, ref: ForwardedRef, -) => ; - -const PaginationLinkPrevious = forwardRef( - _PaginationLinkPrevious, +) => ( + ); +const PaginationLinkPrevious = (forwardRef as PolymorphicForwardRef)(_PaginationLinkPrevious); + export default PaginationLinkPrevious; diff --git a/packages/web-react/src/components/Pagination/README.md b/packages/web-react/src/components/Pagination/README.md index 1f1be887b1..0eb2e24b79 100644 --- a/packages/web-react/src/components/Pagination/README.md +++ b/packages/web-react/src/components/Pagination/README.md @@ -133,6 +133,7 @@ This component extends the [Button][button] component with directional arrows an | -------------------- | ---------------------- | ------- | -------- | -------------------------------------------------------------------- | | `accessibilityLabel` | `string` | `null` | ✓ | Accessibility label of the link | | `direction` | [`previous` \| `next`] | `null` | ✓ | The direction according to which the corresponding icon is displayed | +| `href` | `string` | — | ✓ | Link URL | On top of the API options, the components accept [additional attributes][readme-additional-attributes]. If you need more control over the styling of a component, you can use [style props][readme-style-props] @@ -157,6 +158,7 @@ This component extends the `PaginationButtonLink` component. | Name | Type | Default | Required | Description | | -------------------- | -------- | ------- | -------- | ------------------------------- | | `accessibilityLabel` | `string` | `Next` | ✕ | Accessibility label of the link | +| `href` | `string` | — | ✓ | Link URL | On top of the API options, the components accept [additional attributes][readme-additional-attributes]. If you need more control over the styling of a component, you can use [style props][readme-style-props] @@ -170,6 +172,7 @@ and [escape hatches][readme-escape-hatches]. | `accessibilityLabelNext` | `string` | `Next` | ✕ | Accessibility label of the next link | | `accessibilityLabelPrevious` | `string` | `Previous` | ✕ | Accessibility label of the previous link | | `defaultPage` | `number` | `1` | ✕ | The number of the page selected as current page at the first render | +| `href` | `string` | — | ✓ | Link URL | | `onChange` | `(pageNumber: number) => void` | - | ✕ | On page change callback | | `totalPages` | `number` | 0 | ✓ | Total count of pages | | `visiblePages` | `number` | `5` | ✕ | Number of displayed pages | diff --git a/packages/web-react/src/components/Pagination/UncontrolledPagination.tsx b/packages/web-react/src/components/Pagination/UncontrolledPagination.tsx index 9d106f3c4a..50bbe898e9 100644 --- a/packages/web-react/src/components/Pagination/UncontrolledPagination.tsx +++ b/packages/web-react/src/components/Pagination/UncontrolledPagination.tsx @@ -15,6 +15,7 @@ const UncontrolledPagination = (props: SpiritUncontrolledPaginationProps): JSX.E accessibilityLabelPrevious = 'Previous', accessibilityLabelNext = 'Next', defaultPage = 1, + href, onChange, totalPages = 0, visiblePages = 5, @@ -22,6 +23,7 @@ const UncontrolledPagination = (props: SpiritUncontrolledPaginationProps): JSX.E } = props; const { currentPage, pages, handlePageChange } = usePagination({ defaultPage, + href, onChange, totalPages, visiblePages, @@ -31,6 +33,7 @@ const UncontrolledPagination = (props: SpiritUncontrolledPaginationProps): JSX.E {currentPage !== 1 && ( { event.preventDefault(); @@ -54,6 +57,7 @@ const UncontrolledPagination = (props: SpiritUncontrolledPaginationProps): JSX.E ))} {currentPage !== totalPages && ( { event.preventDefault(); diff --git a/packages/web-react/src/components/Pagination/__tests__/PaginationLink.test.tsx b/packages/web-react/src/components/Pagination/__tests__/PaginationLink.test.tsx index 8c842a3ccd..6c39094d92 100644 --- a/packages/web-react/src/components/Pagination/__tests__/PaginationLink.test.tsx +++ b/packages/web-react/src/components/Pagination/__tests__/PaginationLink.test.tsx @@ -14,14 +14,14 @@ describe('PaginationLink', () => { restPropsTest(PaginationLink, 'a'); it('should render text children', () => { - const dom = render(); + const dom = render(); const element = dom.container.querySelector('.Pagination__link') as HTMLElement; expect(element.textContent).toBe('100'); }); it('should render text children with accessibility label', () => { - const dom = render(); + const dom = render(); const element = dom.container.querySelector('.Pagination__link') as HTMLElement; expect(element.textContent).toBe('Test label100'); diff --git a/packages/web-react/src/components/Pagination/__tests__/UncontrolledPagination.test.tsx b/packages/web-react/src/components/Pagination/__tests__/UncontrolledPagination.test.tsx index 0e4d96970c..bffb5addbc 100644 --- a/packages/web-react/src/components/Pagination/__tests__/UncontrolledPagination.test.tsx +++ b/packages/web-react/src/components/Pagination/__tests__/UncontrolledPagination.test.tsx @@ -11,7 +11,13 @@ describe('UncontrolledPagination', () => { it('renders pagination items with test page selected', () => { render( - , + , ); const items = screen.getAllByRole('button'); @@ -23,7 +29,13 @@ describe('UncontrolledPagination', () => { it('renders disabled items for the first and last page', () => { const { container } = render( - , + , ); const items = screen.getAllByRole('button'); @@ -38,7 +50,13 @@ describe('UncontrolledPagination', () => { it('calls the onPageChange function when an item is clicked', () => { render( - , + , ); const items = screen.getAllByRole('button'); diff --git a/packages/web-react/src/components/Tabs/README.md b/packages/web-react/src/components/Tabs/README.md index b23aaffb16..f28638e4f8 100644 --- a/packages/web-react/src/components/Tabs/README.md +++ b/packages/web-react/src/components/Tabs/README.md @@ -142,6 +142,7 @@ Tab list link | `children` | `any` | — | ✕ | Child component | | `elementType` | `ElementType` | `a` | ✕ | Type of element | | `itemProps` | `StyleProps & HTMLLIElement` | — | ✕ | Props for parent list element | +| `href` | `string` | — | ✕ | TabLink's href attribute | On top of the API options, the components accept [additional attributes][readme-additional-attributes]. If you need more control over the styling of a component, you can use [style props][readme-style-props] diff --git a/packages/web-react/src/components/Tabs/TabLink.tsx b/packages/web-react/src/components/Tabs/TabLink.tsx index b00a18463c..aad6f33913 100644 --- a/packages/web-react/src/components/Tabs/TabLink.tsx +++ b/packages/web-react/src/components/Tabs/TabLink.tsx @@ -3,10 +3,10 @@ import classNames from 'classnames'; import React, { ElementType, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { PolymorphicRef, SpiritTabLinkProps } from '../../types'; +import { PolymorphicForwardRef, PolymorphicRef, SpiritTabLinkProps } from '../../types'; import { useTabsStyleProps } from './useTabsStyleProps'; -const defaultProps: SpiritTabLinkProps = { +const defaultProps: Partial = { itemProps: {}, }; @@ -27,6 +27,6 @@ const _TabLink = (props: SpiritTabLinkProps, ref ); }; -const TabLink = forwardRef>(_TabLink); +const TabLink = (forwardRef as PolymorphicForwardRef)(_TabLink); export default TabLink; diff --git a/packages/web-react/src/components/Toast/README.md b/packages/web-react/src/components/Toast/README.md index 1e22a8e200..f8fa96686f 100644 --- a/packages/web-react/src/components/Toast/README.md +++ b/packages/web-react/src/components/Toast/README.md @@ -231,7 +231,7 @@ Usage example: | ------------- | --------------------------------- | ------- | -------- | ----------------------------- | | `children` | `ReactNode` | — | ✓ | Content of the ToastBarLink | | `elementType` | `ElementType` | `a` | ✕ | Type of element used as | -| `href` | `string` | — | ✕ | ToastBarLink's href attribute | +| `href` | `string` | — | ✓ | ToastBarLink's href attribute | | `ref` | `ForwardedRef` | — | ✕ | Link element reference | On top of the API options, the components accept [additional attributes][readme-additional-attributes]. diff --git a/packages/web-react/src/components/Toast/ToastBarLink.tsx b/packages/web-react/src/components/Toast/ToastBarLink.tsx index 1502fa4a97..9ba34fe941 100644 --- a/packages/web-react/src/components/Toast/ToastBarLink.tsx +++ b/packages/web-react/src/components/Toast/ToastBarLink.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import React, { ElementType, ForwardedRef, forwardRef } from 'react'; import { useStyleProps } from '../../hooks'; -import { ToastLinkProps } from '../../types'; +import { PolymorphicForwardRef, ToastLinkProps } from '../../types'; import { useToastBarStyleProps } from './useToastBarStyleProps'; const defaultProps: Partial = { @@ -29,6 +29,6 @@ const _ToastBarLink = (props: ToastLinkProps, ref: ForwardedRef(_ToastBarLink); +const ToastBarLink = (forwardRef as PolymorphicForwardRef)(_ToastBarLink); export default ToastBarLink; diff --git a/packages/web-react/src/components/Toast/ToastContext.tsx b/packages/web-react/src/components/Toast/ToastContext.tsx index 7b00990889..66b8364651 100644 --- a/packages/web-react/src/components/Toast/ToastContext.tsx +++ b/packages/web-react/src/components/Toast/ToastContext.tsx @@ -24,7 +24,6 @@ export interface ToastItem { link?: JSX.Element | string; }; } - export interface ToastContextType extends ToastState { clear: () => void; hide: (id: string) => void; @@ -81,6 +80,7 @@ type ActionType = | { type: 'clear'; payload: null } | { type: 'setQueue'; payload: { newQueue: ToastItem[] } }; +// Update the reducer in `packages/web-react/src/components/Toast/ToastContext.tsx` const reducer = (state: ToastState, action: ActionType): ToastState => { const { type, payload } = action; const { queue: currentQueue } = state; @@ -97,7 +97,12 @@ const reducer = (state: ToastState, action: ActionType): ToastState => { iconName: payload.options?.iconName, id: payload.toastId, isDismissible: payload.options?.isDismissible || false, - linkProps: payload.options?.linkProps || {}, + linkProps: { + href: payload.options?.linkProps.href || '', + elementType: payload.options?.linkProps.elementType || 'a', + target: payload.options?.linkProps.target, + title: payload.options?.linkProps.title, + }, isOpen: true, content: { message: payload.content.message, diff --git a/packages/web-react/src/types/button.ts b/packages/web-react/src/types/button.ts index 36106c1902..49a5cdb7af 100644 --- a/packages/web-react/src/types/button.ts +++ b/packages/web-react/src/types/button.ts @@ -8,6 +8,7 @@ import { SpiritPolymorphicElementPropsWithRef, SizesDictionaryType, StyleProps, + LinkHrefProps, } from './shared'; export type ButtonColor = ActionButtonColorsDictionaryType | EmotionColorsDictionaryType | C; @@ -57,4 +58,5 @@ export type SpiritButtonProps>; export type SpiritButtonLinkProps = ButtonLinkProps & + LinkHrefProps & SpiritPolymorphicElementPropsWithRef>; diff --git a/packages/web-react/src/types/header.ts b/packages/web-react/src/types/header.ts index 3e4e18923f..00ff40673e 100644 --- a/packages/web-react/src/types/header.ts +++ b/packages/web-react/src/types/header.ts @@ -2,6 +2,7 @@ import { ElementType } from 'react'; import { ChildrenProps, ClickEvent, + LinkHrefProps, SpiritButtonElementProps, SpiritDialogElementProps, SpiritElementProps, @@ -65,6 +66,7 @@ export type HeaderDialogLinkProps = { } & BaseHeaderDialogLinkProps; export type SpiritDialogHeaderLinkProps = HeaderDialogLinkProps & + LinkHrefProps & SpiritPolymorphicElementPropsWithRef>; export interface HeaderDialogNavProps extends SpiritUListElementProps, ChildrenProps {} @@ -87,6 +89,7 @@ export type HeaderLinkProps = { } & HeaderLinkBaseProps; export type SpiritHeaderLinkProps = HeaderLinkProps & + LinkHrefProps & SpiritPolymorphicElementPropsWithRef>; export interface HeaderMobileActionsProps extends SpiritElementProps, HeaderMobileActionsHandlingProps, ChildrenProps { diff --git a/packages/web-react/src/types/link.ts b/packages/web-react/src/types/link.ts index 0892f25850..83d3f634ee 100644 --- a/packages/web-react/src/types/link.ts +++ b/packages/web-react/src/types/link.ts @@ -2,6 +2,7 @@ import { ElementType } from 'react'; import { ActionLinkColorsDictionaryType, ChildrenProps, + LinkHrefProps, SpiritPolymorphicElementPropsWithRef, StyleProps, TransferProps, @@ -13,19 +14,20 @@ export const UNDERLINED_OPTIONS = { NEVER: 'never', } as const; +export type UnderlinedDictionaryKeys = keyof typeof UNDERLINED_OPTIONS; +export type UnderlinedDictionaryType = (typeof UNDERLINED_OPTIONS)[UnderlinedDictionaryKeys]; + export type LinkTarget = '_blank' | '_self' | '_parent' | '_top'; export type UnderlineOptions = (typeof UNDERLINED_OPTIONS)[keyof typeof UNDERLINED_OPTIONS]; export interface LinkBaseProps extends ChildrenProps, StyleProps, TransferProps { - /** Link's href attribute */ - href?: string; /** Link's target attribute */ target?: LinkTarget; /** Color of the Link */ color?: ActionLinkColorsDictionaryType; /** When is the Link underlined */ - underlined?: UnderlineOptions; + underlined?: UnderlinedDictionaryType | string; /** Whether is the Link disabled */ isDisabled?: boolean; } @@ -40,4 +42,5 @@ export type LinkProps = { } & LinkBaseProps; export type SpiritLinkProps = LinkProps & + LinkHrefProps & SpiritPolymorphicElementPropsWithRef>; diff --git a/packages/web-react/src/types/pagination.ts b/packages/web-react/src/types/pagination.ts index 7327c1ea6d..763c08b3e8 100644 --- a/packages/web-react/src/types/pagination.ts +++ b/packages/web-react/src/types/pagination.ts @@ -1,7 +1,8 @@ import { ElementType } from 'react'; -import { SpiritButtonProps } from './button'; +import { SpiritButtonLinkProps } from './button'; import { ChildrenProps, + LinkHrefProps, SpiritElementProps, SpiritLItemElementProps, SpiritPolymorphicElementPropsWithRef, @@ -31,18 +32,20 @@ export interface PaginationLinkProps pageNumber: number; } -export type PaginationButtonLinkProps = SpiritButtonProps & +export type PaginationButtonLinkProps = SpiritButtonLinkProps & AriaPaginationProps & { direction: PaginationLinkDirectionType; }; -export type PaginationLinkPreviousNextProps = SpiritButtonProps & AriaPaginationProps; +export type PaginationLinkPreviousNextProps = SpiritButtonLinkProps & + AriaPaginationProps; export interface SpiritPaginationProps extends PaginationProps {} export interface SpiritPaginationItemProps extends PaginationItemProps {} export type SpiritPaginationLinkProps = PaginationLinkProps & + LinkHrefProps & SpiritPolymorphicElementPropsWithRef>; export type SpiritPaginationButtonLinkProps = PaginationButtonLinkProps; @@ -53,6 +56,7 @@ export interface UncontrolledPaginationProps { accessibilityLabelNext?: string; accessibilityLabelPrevious?: string; defaultPage?: number; + href: string; visiblePages?: number; onChange?: (pageNumber: number) => void; totalPages: number; diff --git a/packages/web-react/src/types/shared/index.ts b/packages/web-react/src/types/shared/index.ts index dcdbf8492b..34dadeba5b 100644 --- a/packages/web-react/src/types/shared/index.ts +++ b/packages/web-react/src/types/shared/index.ts @@ -10,6 +10,7 @@ export * from './element'; export * from './events'; export * from './inputs'; export * from './item'; +export * from './links'; export * from './positions'; export * from './refs'; export * from './rest'; diff --git a/packages/web-react/src/types/shared/links.ts b/packages/web-react/src/types/shared/links.ts new file mode 100644 index 0000000000..9f7edeefda --- /dev/null +++ b/packages/web-react/src/types/shared/links.ts @@ -0,0 +1,5 @@ +import { ElementType } from 'react'; + +export type LinkHrefProps = E extends 'a' + ? { href: string; elementType?: E; target?: '_blank'; title?: string } + : { href?: string; elementType: E }; diff --git a/packages/web-react/src/types/shared/refs.ts b/packages/web-react/src/types/shared/refs.ts index 7b66377c43..ece393fb83 100644 --- a/packages/web-react/src/types/shared/refs.ts +++ b/packages/web-react/src/types/shared/refs.ts @@ -1,7 +1,11 @@ -import { Ref } from 'react'; +import { Ref, RefAttributes } from 'react'; export interface DOMRefValue { UNSAFE_getDOMNode(): T; } export type DOMRef = Ref>; + +export type PolymorphicForwardRef = ( + render: (props: P, ref: Ref) => JSX.Element, +) => (props: P & RefAttributes) => JSX.Element; diff --git a/packages/web-react/src/types/tabs.ts b/packages/web-react/src/types/tabs.ts index b7a79fce94..fd8f066e65 100644 --- a/packages/web-react/src/types/tabs.ts +++ b/packages/web-react/src/types/tabs.ts @@ -2,6 +2,7 @@ import { ElementType, HTMLProps } from 'react'; import { ChildrenProps, ClickEvents, + LinkHrefProps, SpacingProp, SpiritPolymorphicElementPropsWithRef, StyleProps, @@ -47,6 +48,7 @@ export type TabLinkProps = { } & TabLinkBaseProps; export type SpiritTabLinkProps = TabLinkProps & + LinkHrefProps & SpiritPolymorphicElementPropsWithRef>; export type TabsToggler = (id: TabId) => void; diff --git a/packages/web-react/src/types/toast.ts b/packages/web-react/src/types/toast.ts index c3df58a704..25d2a47a54 100644 --- a/packages/web-react/src/types/toast.ts +++ b/packages/web-react/src/types/toast.ts @@ -5,6 +5,7 @@ import { AlignmentYDictionaryType, ChildrenProps, EmotionColorsDictionaryType, + LinkHrefProps, StyleProps, } from './shared'; @@ -41,11 +42,12 @@ export interface SpiritToastBarProps extends ToastBarProps, TransitionToastBarPr id: string; } -export interface ToastLinkProps extends ToastBarHandlingProps, ToastBarProps { - elementType?: E; - href?: string; - target?: LinkTarget; -} +export type ToastLinkProps = ToastBarHandlingProps & + ToastBarProps & + LinkHrefProps & { + elementType?: E; + target?: LinkTarget; + }; export interface ToastCloseButtonProps extends ToastBarHandlingProps, SpiritToastBarProps { label?: string;