mirror of
https://github.com/grafana/grafana.git
synced 2024-12-01 13:09:22 -06:00
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:
parent
de3bcb6071
commit
c13f247a94
@ -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();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
Loading…
Reference in New Issue
Block a user