From f2f814a6168309d4cdc7f6d971239bfc96f35af7 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Fri, 6 Jun 2025 09:18:57 +0200 Subject: [PATCH 1/2] Add render prop to Button Signed-off-by: Charles de Dreuille --- .changeset/kind-houses-feel.md | 5 ++ packages/canon/report.api.md | 6 +- .../src/components/Button/Button.stories.tsx | 12 ++++ .../canon/src/components/Button/Button.tsx | 72 ++++++++++--------- packages/canon/src/components/Button/types.ts | 9 +-- 5 files changed, 60 insertions(+), 44 deletions(-) create mode 100644 .changeset/kind-houses-feel.md diff --git a/.changeset/kind-houses-feel.md b/.changeset/kind-houses-feel.md new file mode 100644 index 0000000000..a4b3ac0d14 --- /dev/null +++ b/.changeset/kind-houses-feel.md @@ -0,0 +1,5 @@ +--- +'@backstage/canon': patch +--- + +Added a render prop to the Button component in Canon to use it as a link. diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index bc0ad71e90..b6ce130ecc 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -149,7 +149,7 @@ export const breakpoints: Breakpoint[]; // @public (undocumented) export const Button: ForwardRefExoticComponent< - ButtonProps & RefAttributes + Omit & RefAttributes >; // @public (undocumented) @@ -174,9 +174,7 @@ export const buttonPropDefs: { }; // @public -export interface ButtonProps - extends Omit, 'children'> { - children: React.ReactNode; +export interface ButtonProps extends useRender.ComponentProps<'button'> { iconEnd?: ReactElement; iconStart?: ReactElement; size?: ButtonOwnProps['size']; diff --git a/packages/canon/src/components/Button/Button.stories.tsx b/packages/canon/src/components/Button/Button.stories.tsx index c0519cb279..2034f8a3d4 100644 --- a/packages/canon/src/components/Button/Button.stories.tsx +++ b/packages/canon/src/components/Button/Button.stories.tsx @@ -131,6 +131,18 @@ export const Disabled: Story = { ), }; +export const AsLink: Story = { + args: { + children: 'Button', + }, + render: args => ( + - ); + const { renderElement } = useRender({ + render, + props: { + className: clsx('canon-Button', className), + ['data-variant']: responsiveVariant, + ['data-size']: responsiveSize, + ...rest, + children: ( + <> + {iconStart && ( + + )} + {children} + {iconEnd && ( + + )} + + ), + }, + refs: [ref, internalRef], + }); + + return renderElement(); }, ); diff --git a/packages/canon/src/components/Button/types.ts b/packages/canon/src/components/Button/types.ts index 4ab62d5683..e91538299e 100644 --- a/packages/canon/src/components/Button/types.ts +++ b/packages/canon/src/components/Button/types.ts @@ -16,14 +16,14 @@ import type { ButtonOwnProps } from './Button.props'; import { ReactElement } from 'react'; +import type { useRender } from '@base-ui-components/react/use-render'; /** * Properties for {@link Button} * * @public */ -export interface ButtonProps - extends Omit, 'children'> { +export interface ButtonProps extends useRender.ComponentProps<'button'> { /** * The size of the button * @defaultValue 'medium' @@ -36,11 +36,6 @@ export interface ButtonProps */ variant?: ButtonOwnProps['variant']; - /** - * The content of the button - */ - children: React.ReactNode; - /** * Optional icon to display at the start of the button */ From a61671f5ae84b7b3d3723f12ca671a99ab0ef4d1 Mon Sep 17 00:00:00 2001 From: Charles de Dreuille Date: Fri, 6 Jun 2025 09:39:04 +0200 Subject: [PATCH 2/2] Improve docs Signed-off-by: Charles de Dreuille --- .../src/app/(docs)/components/button/page.mdx | 14 ++++++++++++++ .../src/app/(docs)/components/button/props.ts | 6 ++++++ .../canon/src/components/Button/Button.stories.tsx | 4 ++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/canon-docs/src/app/(docs)/components/button/page.mdx b/canon-docs/src/app/(docs)/components/button/page.mdx index e1ecee8920..3554ee39f9 100644 --- a/canon-docs/src/app/(docs)/components/button/page.mdx +++ b/canon-docs/src/app/(docs)/components/button/page.mdx @@ -125,6 +125,20 @@ Here's a view when buttons are disabled. code={``} /> +### As Link + +Here's a view when buttons are rendered as a link. + +} + code={``} +/> + ### Responsive Here's a view when buttons are responsive. diff --git a/canon-docs/src/app/(docs)/components/button/props.ts b/canon-docs/src/app/(docs)/components/button/props.ts index 813dcaa6f0..36b0f73066 100644 --- a/canon-docs/src/app/(docs)/components/button/props.ts +++ b/canon-docs/src/app/(docs)/components/button/props.ts @@ -14,6 +14,12 @@ export const buttonPropDefs: Record = { default: 'medium', responsive: true, }, + render: { + type: 'enum', + values: ['ReactNode'], + responsive: false, + default: '