Card: Defend against conditional action buttons (#35204)

* fix(card): defend against invalid elements types passed to BaseActions

* test(card): add test to support conditional buttons being passed in

* fix(playlistpage): remove disabled prop from LinkButton for editors

* chore(playlistpage): remove title from edit button
This commit is contained in:
Jack Westbrook 2021-06-04 14:38:29 +02:00 committed by GitHub
parent de3bcb6071
commit c13f247a94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 12 deletions

View File

@ -72,5 +72,23 @@ describe('Card', () => {
expect(screen.getByRole('button', { name: 'Click Me' })).not.toBeDisabled(); expect(screen.getByRole('button', { name: 'Click Me' })).not.toBeDisabled();
expect(screen.getByRole('button', { name: 'Delete' })).not.toBeDisabled(); expect(screen.getByRole('button', { name: 'Delete' })).not.toBeDisabled();
}); });
it('Children should be conditional', () => {
const shouldNotRender = false;
render(
<Card heading="Test Heading">
<Card.Actions>
<Button>Click Me</Button>
{shouldNotRender && <Button>Delete</Button>}
</Card.Actions>
<Card.SecondaryActions>
{shouldNotRender && <IconButton name="trash-alt" aria-label="Delete" disabled={false} />}
</Card.SecondaryActions>
</Card>
);
expect(screen.getByRole('button', { name: 'Click Me' })).not.toBeDisabled();
expect(screen.queryByRole('button', { name: 'Delete' })).not.toBeInTheDocument();
});
}); });
}); });

View File

@ -243,7 +243,7 @@ const Meta: FC<ChildProps & { separator?: string }> = memo(({ children, styles,
Meta.displayName = 'Meta'; Meta.displayName = 'Meta';
interface ActionsProps extends ChildProps { interface ActionsProps extends ChildProps {
children: JSX.Element | JSX.Element[]; children?: React.ReactNode;
variant?: 'primary' | 'secondary'; variant?: 'primary' | 'secondary';
} }
@ -251,9 +251,9 @@ const BaseActions: FC<ActionsProps> = ({ children, styles, disabled, variant })
const css = variant === 'primary' ? styles?.actions : styles?.secondaryActions; const css = variant === 'primary' ? styles?.actions : styles?.secondaryActions;
return ( return (
<div className={css}> <div className={css}>
{Array.isArray(children) {React.Children.map(children, (child) => {
? React.Children.map(children, (child) => cloneElement(child, { disabled, ...child.props })) return React.isValidElement(child) ? cloneElement(child, { disabled, ...child.props }) : null;
: cloneElement(children, { disabled, ...children.props })} })}
</div> </div>
); );
}; };

View File

@ -51,14 +51,7 @@ export const PlaylistPage: FC<Props> = ({ navModel }) => {
Start playlist Start playlist
</Button> </Button>
{contextSrv.isEditor && ( {contextSrv.isEditor && (
<LinkButton <LinkButton key="edit" variant="secondary" href={`/playlists/edit/${playlist.id}`} icon="cog">
key="edit"
variant="secondary"
href={`/playlists/edit/${playlist.id}`}
icon="cog"
disabled
title="Feature temporarily disabled"
>
Edit playlist Edit playlist
</LinkButton> </LinkButton>
)} )}