Merge pull request #31276 from backstage/fix/buttonlink-router-integration
fix(bui): fix button link internal routing
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/ui': patch
|
||||
---
|
||||
|
||||
Add react router for internal routing for ButtonLinks
|
||||
@@ -14,15 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||
import type { Meta, StoryFn, StoryObj } from '@storybook/react-vite';
|
||||
import { ButtonLink } from './ButtonLink';
|
||||
import { Flex } from '../Flex';
|
||||
import { Text } from '../Text';
|
||||
import { Icon } from '../Icon';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
|
||||
const meta = {
|
||||
title: 'Backstage UI/ButtonLink',
|
||||
component: ButtonLink,
|
||||
decorators: [
|
||||
(Story: StoryFn) => (
|
||||
<MemoryRouter>
|
||||
<Story />
|
||||
</MemoryRouter>
|
||||
),
|
||||
],
|
||||
argTypes: {
|
||||
size: {
|
||||
control: 'select',
|
||||
|
||||
@@ -16,13 +16,16 @@
|
||||
|
||||
import clsx from 'clsx';
|
||||
import { forwardRef, Ref } from 'react';
|
||||
import { Link as RALink } from 'react-aria-components';
|
||||
import { Link as RALink, RouterProvider } from 'react-aria-components';
|
||||
import { useNavigate, useHref } from 'react-router-dom';
|
||||
import type { ButtonLinkProps } from './types';
|
||||
import { useStyles } from '../../hooks/useStyles';
|
||||
import { isExternalLink } from '../../utils/isExternalLink';
|
||||
|
||||
/** @public */
|
||||
export const ButtonLink = forwardRef(
|
||||
(props: ButtonLinkProps, ref: Ref<HTMLAnchorElement>) => {
|
||||
const navigate = useNavigate();
|
||||
const {
|
||||
size = 'small',
|
||||
variant = 'primary',
|
||||
@@ -30,6 +33,7 @@ export const ButtonLink = forwardRef(
|
||||
iconEnd,
|
||||
children,
|
||||
className,
|
||||
href,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@@ -40,17 +44,48 @@ export const ButtonLink = forwardRef(
|
||||
|
||||
const { classNames: classNamesButtonLink } = useStyles('ButtonLink');
|
||||
|
||||
const isExternal = isExternalLink(href);
|
||||
|
||||
// If it's an external link, render RALink without RouterProvider
|
||||
if (isExternal) {
|
||||
return (
|
||||
<RALink
|
||||
className={clsx(
|
||||
classNames.root,
|
||||
classNamesButtonLink.root,
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...dataAttributes}
|
||||
href={href}
|
||||
{...rest}
|
||||
>
|
||||
{iconStart}
|
||||
{children}
|
||||
{iconEnd}
|
||||
</RALink>
|
||||
);
|
||||
}
|
||||
|
||||
// For internal links, use RouterProvider
|
||||
return (
|
||||
<RALink
|
||||
className={clsx(classNames.root, classNamesButtonLink.root, className)}
|
||||
ref={ref}
|
||||
{...dataAttributes}
|
||||
{...rest}
|
||||
>
|
||||
{iconStart}
|
||||
{children}
|
||||
{iconEnd}
|
||||
</RALink>
|
||||
<RouterProvider navigate={navigate} useHref={useHref}>
|
||||
<RALink
|
||||
className={clsx(
|
||||
classNames.root,
|
||||
classNamesButtonLink.root,
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
{...dataAttributes}
|
||||
href={href}
|
||||
{...rest}
|
||||
>
|
||||
{iconStart}
|
||||
{children}
|
||||
{iconEnd}
|
||||
</RALink>
|
||||
</RouterProvider>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user