diff --git a/.changeset/ten-dodos-lead.md b/.changeset/ten-dodos-lead.md new file mode 100644 index 0000000000..340c5170cf --- /dev/null +++ b/.changeset/ten-dodos-lead.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +We added a render prop to the Link component to make sure it can work with React Router. diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index 766b40febd..7335ee93f3 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -15,6 +15,7 @@ import { RefAttributes } from 'react'; import type { RemixiconComponentType } from '@remixicon/react'; import { ScrollArea as ScrollArea_2 } from '@base-ui-components/react/scroll-area'; import { Tooltip as Tooltip_2 } from '@base-ui-components/react/tooltip'; +import type { useRender } from '@base-ui-components/react/use-render'; // @public (undocumented) export type AlignItems = 'stretch' | 'start' | 'center' | 'end'; @@ -696,6 +697,32 @@ export type JustifyContent = | 'around' | 'between'; +// @public (undocumented) +export const Link: React_2.ForwardRefExoticComponent< + Omit & React_2.RefAttributes +>; + +// @public (undocumented) +export interface LinkProps extends useRender.ComponentProps<'a'> { + // (undocumented) + children: ReactNode; + // (undocumented) + className?: string; + // (undocumented) + style?: CSSProperties; + // (undocumented) + to?: string; + // (undocumented) + variant?: + | 'subtitle' + | 'body' + | 'caption' + | 'label' + | Partial>; + // (undocumented) + weight?: 'regular' | 'bold' | Partial>; +} + // @public (undocumented) export const marginPropDefs: (spacingValues: string[]) => { m: { diff --git a/packages/canon/src/components/Link/Link.stories.tsx b/packages/canon/src/components/Link/Link.stories.tsx index 38e71c310a..bdaa4006ae 100644 --- a/packages/canon/src/components/Link/Link.stories.tsx +++ b/packages/canon/src/components/Link/Link.stories.tsx @@ -19,6 +19,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { Link } from './Link'; import { Flex } from '../Flex'; import { Text } from '../Text'; +import { Link as RouterLink, MemoryRouter } from 'react-router-dom'; const meta = { title: 'Components/Link', @@ -33,7 +34,7 @@ type Story = StoryObj; export const Default: Story = { args: { - href: 'https://canon.backstage.io', + to: 'https://canon.backstage.io', children: 'Sign up for Backstage', }, }; @@ -66,6 +67,7 @@ export const AllWeights: Story = { export const Responsive: Story = { args: { + ...Default.args, variant: { xs: 'label', md: 'body', @@ -73,6 +75,23 @@ export const Responsive: Story = { }, }; +export const CustomRender: Story = { + render: () => { + return ( + + }>Go to Catalog + + ); + }, + decorators: [ + Story => ( + + + + ), + ], +}; + export const Playground: Story = { args: { ...Default.args, diff --git a/packages/canon/src/components/Link/Link.tsx b/packages/canon/src/components/Link/Link.tsx index 8763575bf9..e9d0d6aadf 100644 --- a/packages/canon/src/components/Link/Link.tsx +++ b/packages/canon/src/components/Link/Link.tsx @@ -15,41 +15,43 @@ */ import React, { forwardRef } from 'react'; +import { useRender } from '@base-ui-components/react/use-render'; import { useResponsiveValue } from '../../hooks/useResponsiveValue'; import clsx from 'clsx'; import type { LinkProps } from './types'; /** @public */ -export const Link = forwardRef((props, ref) => { +export const Link = forwardRef((props, ref) => { const { - children, + className, variant = 'body', weight = 'regular', - style, - className, + render = , ...restProps } = props; - // Get the responsive values for the variant and weight const responsiveVariant = useResponsiveValue(variant); const responsiveWeight = useResponsiveValue(weight); + const internalRef = React.useRef(null); - return ( - - {children} - - ); + ), + responsiveVariant, + responsiveWeight, + ...restProps, + }, + refs: [ref, internalRef], + }); + + return renderElement(); }); Link.displayName = 'Link'; diff --git a/packages/canon/src/components/Link/types.ts b/packages/canon/src/components/Link/types.ts index 4c5b34e14e..20fa4a2f31 100644 --- a/packages/canon/src/components/Link/types.ts +++ b/packages/canon/src/components/Link/types.ts @@ -16,11 +16,12 @@ import type { CSSProperties, ReactNode } from 'react'; import type { Breakpoint } from '../../types'; +import type { useRender } from '@base-ui-components/react/use-render'; /** @public */ -export interface LinkProps - extends React.AnchorHTMLAttributes { +export interface LinkProps extends useRender.ComponentProps<'a'> { children: ReactNode; + to?: string; variant?: | 'subtitle' | 'body' diff --git a/packages/canon/src/index.ts b/packages/canon/src/index.ts index 7435b6dd60..815e153c19 100644 --- a/packages/canon/src/index.ts +++ b/packages/canon/src/index.ts @@ -41,6 +41,7 @@ export * from './components/TextField'; export * from './components/Tooltip'; export * from './components/Menu'; export * from './components/ScrollArea'; +export * from './components/Link'; export * from './components/Select'; // Types