diff --git a/packages/canon/report.api.md b/packages/canon/report.api.md index b648025251..96e9e31235 100644 --- a/packages/canon/report.api.md +++ b/packages/canon/report.api.md @@ -5,13 +5,15 @@ ```ts import { Avatar as Avatar_2 } from '@base-ui-components/react/avatar'; import { Breakpoint as Breakpoint_2 } from '@backstage/canon'; +import { Button as Button_2 } from 'react-aria-components'; import { ChangeEvent } from 'react'; import { Collapsible as Collapsible_2 } from '@base-ui-components/react/collapsible'; import { ComponentProps } from 'react'; -import type { ComponentPropsWithRef } from 'react'; +import { ComponentPropsWithoutRef } from 'react'; +import { ComponentPropsWithRef } from 'react'; import { Context } from 'react'; import type { CSSProperties } from 'react'; -import type { ElementType } from 'react'; +import { ElementType } from 'react'; import { FC } from 'react'; import { FocusEvent as FocusEvent_2 } from 'react'; import { ForwardRefExoticComponent } from 'react'; @@ -43,8 +45,8 @@ export type ArbitraryStylingPropDef = { }; // @public (undocumented) -export type AsProp = { - as?: C; +export type As = { + as?: TAs; }; // @public (undocumented) @@ -156,14 +158,20 @@ export type Breakpoint = 'initial' | 'xs' | 'sm' | 'md' | 'lg' | 'xl'; export const breakpoints: Breakpoint[]; // @public (undocumented) -export const Button: ( - props: ButtonProps, -) => JSX_2.Element; +export const Button: { + ( + props: ButtonProps & { + ref?: ComponentPropsWithRef['ref']; + }, + ): ReactElement; + displayName: string; +}; // @public -export type ButtonProps = PolymorphicComponentProp< - C, +export type ButtonProps = PolymorphicComponentProps< + TAs, { + children?: ReactNode; size?: | 'small' | 'medium' @@ -685,14 +693,19 @@ export type HeightProps = GetPropDefTypes; export const Icon: (props: IconProps) => JSX_2.Element | null; // @public (undocumented) -export const IconButton: ( - props: IconButtonProps, -) => JSX_2.Element; +export const IconButton: { + ( + props: IconButtonProps & { + ref?: ComponentPropsWithRef['ref']; + }, + ): ReactElement; + displayName: string; +}; // @public -export type IconButtonProps = - PolymorphicComponentProp< - C, +export type IconButtonProps = + PolymorphicComponentProps< + TAs, { size?: | 'small' @@ -1002,11 +1015,12 @@ export const paddingPropDefs: (spacingValues: string[]) => { export type PaddingProps = GetPropDefTypes; // @public -export type PolymorphicComponentProp< - C extends React.ElementType, - Props = {}, -> = React.PropsWithChildren> & - Omit, PropsToOmit>; +export type PolymorphicComponentProps< + TAs extends ElementType, + TProps = {}, +> = TProps & + As & + Omit, keyof (As & TProps)>; // @public (undocumented) export const positionPropDefs: { @@ -1024,9 +1038,6 @@ export type PositionProps = GetPropDefTypes; // @public (undocumented) export type PropDef = RegularPropDef | ResponsivePropDef; -// @public (undocumented) -export type PropsToOmit = keyof (AsProp & P); - // @public (undocumented) export type ReactNodePropDef = { type: 'ReactNode'; diff --git a/packages/canon/src/components/Button/Button.stories.tsx b/packages/canon/src/components/Button/Button.stories.tsx index 30559d2698..7baff061b3 100644 --- a/packages/canon/src/components/Button/Button.stories.tsx +++ b/packages/canon/src/components/Button/Button.stories.tsx @@ -212,7 +212,7 @@ export const Playground: Story = { @@ -220,7 +220,7 @@ export const Playground: Story = { iconStart={} variant={variant as ButtonProps['variant']} size={size as ButtonProps['size']} - disabled + isDisabled > Button @@ -228,7 +228,7 @@ export const Playground: Story = { iconEnd={} variant={variant as ButtonProps['variant']} size={size as ButtonProps['size']} - disabled + isDisabled > Button diff --git a/packages/canon/src/components/IconButton/IconButton.stories.tsx b/packages/canon/src/components/IconButton/IconButton.stories.tsx index 110db0aa89..4065b61cb2 100644 --- a/packages/canon/src/components/IconButton/IconButton.stories.tsx +++ b/packages/canon/src/components/IconButton/IconButton.stories.tsx @@ -40,44 +40,45 @@ export default meta; type Story = StoryObj; export const Default: Story = { - render: args => } />, + render: () => } />, }; export const Variants: Story = { - render: args => ( + render: () => ( - } variant="primary" /> - } variant="secondary" /> + } variant="primary" /> + } variant="secondary" /> ), }; export const Sizes: Story = { - render: args => ( + render: () => ( - } size="small" /> - } size="medium" /> + } size="small" /> + } size="medium" /> ), }; export const Disabled: Story = { - args: { disabled: true }, - render: args => ( + render: () => ( - } variant="primary" /> - } variant="secondary" /> + } variant="primary" /> + } variant="secondary" /> ), }; export const AsLink: Story = { - args: { - as: 'a', - href: 'https://canon.backstage.io', - target: '_blank', - }, - render: args => } />, + render: () => ( + } + /> + ), }; export const AsComponent: Story = { diff --git a/packages/canon/src/components/IconButton/IconButton.tsx b/packages/canon/src/components/IconButton/IconButton.tsx index 079aa2e6f4..dfa06cb612 100644 --- a/packages/canon/src/components/IconButton/IconButton.tsx +++ b/packages/canon/src/components/IconButton/IconButton.tsx @@ -15,42 +15,57 @@ */ import clsx from 'clsx'; +import { + ComponentPropsWithRef, + ElementType, + forwardRef, + ReactElement, + Ref, +} from 'react'; +import { Button as RAButton } from 'react-aria-components'; import { useResponsiveValue } from '../../hooks/useResponsiveValue'; import type { IconButtonProps } from './types'; /** @public */ -export const IconButton = ( - props: IconButtonProps, -) => { - const { - as, - size = 'small', - variant = 'primary', - icon, - className, - href, - style, - ...rest - } = props; +export const IconButton = forwardRef( + (props: IconButtonProps, ref: Ref) => { + const { + as, + size = 'small', + variant = 'primary', + icon, + className, + style, + ...rest + } = props; - const Component = as || 'button'; - const responsiveSize = useResponsiveValue(size); - const responsiveVariant = useResponsiveValue(variant); + const Component = as || RAButton; + const responsiveSize = useResponsiveValue(size); + const responsiveVariant = useResponsiveValue(variant); - return ( - - - - ); + + + ); + }, +) as { + ( + props: IconButtonProps & { ref?: ComponentPropsWithRef['ref'] }, + ): ReactElement; + displayName: string; }; + +IconButton.displayName = 'IconButton'; diff --git a/packages/canon/src/components/IconButton/types.ts b/packages/canon/src/components/IconButton/types.ts index f15831e4a4..1d3deb94c2 100644 --- a/packages/canon/src/components/IconButton/types.ts +++ b/packages/canon/src/components/IconButton/types.ts @@ -15,17 +15,17 @@ */ import { Breakpoint } from '@backstage/canon'; -import { ReactElement } from 'react'; -import { PolymorphicComponentProp } from '../../types'; +import { ElementType, ReactElement } from 'react'; +import { PolymorphicComponentProps } from '../../types'; /** * Properties for {@link IconButton} * * @public */ -export type IconButtonProps = - PolymorphicComponentProp< - C, +export type IconButtonProps = + PolymorphicComponentProps< + TAs, { size?: | 'small'