grafana/ui: Add noMargin prop to Card (#105604)

grafana/ui: Add noMargin to Card
This commit is contained in:
Alex Khomenko
2025-05-22 12:03:58 +03:00
committed by GitHub
parent 5299602211
commit ec48b0dfcb
4 changed files with 32 additions and 32 deletions

View File

@ -100,7 +100,7 @@ export const Examples: StoryFn<typeof Button> = () => {
<Button variant="secondary" icon="angle-down" />
</ButtonGroup>
</Stack>
<Card>
<Card noMargin>
<Card.Heading>Button inside card</Card.Heading>
<Card.Actions>
{allButtonVariants.map((variant) => (

View File

@ -15,7 +15,7 @@ const meta: Meta<typeof Card> = {
tags: ['autodocs', 'nosort'],
parameters: {
controls: {
exclude: ['onClick', 'href', 'heading', 'description', 'className'],
exclude: ['onClick', 'href', 'heading', 'description', 'className', 'noMargin'],
},
},
};
@ -25,7 +25,7 @@ const meta: Meta<typeof Card> = {
*/
export const Basic: StoryFn<typeof Card> = (args) => {
return (
<Card {...args}>
<Card noMargin {...args}>
<Card.Heading>Filter by name</Card.Heading>
<Card.Description>
Filter data by query. This is useful if you are sharing the results from a different panel that has many queries
@ -41,7 +41,7 @@ export const Basic: StoryFn<typeof Card> = (args) => {
*/
export const MultipleMetadataElements: StoryFn<typeof Card> = (args) => {
return (
<Card>
<Card noMargin>
<Card.Heading>Test dashboard</Card.Heading>
<Card.Meta>{['Folder: Test', 'Views: 100']}</Card.Meta>
</Card>
@ -54,7 +54,7 @@ export const MultipleMetadataElements: StoryFn<typeof Card> = (args) => {
*/
export const ComplexMetadataElements: StoryFn<typeof Card> = (args) => {
return (
<Card>
<Card noMargin>
<Card.Heading>Test dashboard</Card.Heading>
<Card.Meta>
<>Grafana</>
@ -71,7 +71,7 @@ export const ComplexMetadataElements: StoryFn<typeof Card> = (args) => {
*/
export const MultipleMetadataWithCustomSeparator: StoryFn<typeof Card> = (args) => {
return (
<Card>
<Card noMargin>
<Card.Heading>Test dashboard</Card.Heading>
<Card.Meta separator={'-'}>
Grafana
@ -90,7 +90,7 @@ export const MultipleMetadataWithCustomSeparator: StoryFn<typeof Card> = (args)
*/
export const Tags: StoryFn<typeof Card> = (args) => {
return (
<Card>
<Card noMargin>
<Card.Heading>Test dashboard</Card.Heading>
<Card.Description>Card with a list of tags</Card.Description>
<Card.Tags>
@ -105,7 +105,7 @@ export const Tags: StoryFn<typeof Card> = (args) => {
*/
export const AsALink: StoryFn<typeof Card> = (args) => {
return (
<Card href="https://grafana.com">
<Card noMargin href="https://grafana.com">
<Card.Heading>Redirect to Grafana</Card.Heading>
<Card.Description>Clicking this card will redirect to grafana website</Card.Description>
</Card>
@ -119,7 +119,7 @@ export const AsALink: StoryFn<typeof Card> = (args) => {
*/
export const AsAButton: StoryFn<typeof Card> = (args) => {
return (
<Card onClick={() => alert('Hello, Grafana!')}>
<Card noMargin onClick={() => alert('Hello, Grafana!')}>
<Card.Heading>Hello, Grafana</Card.Heading>
<Card.Description>Clicking this card will create an alert</Card.Description>
</Card>
@ -131,27 +131,27 @@ export const AsAButton: StoryFn<typeof Card> = (args) => {
*/
export const InsideAListItem: StoryFn<typeof Card> = (args) => {
return (
<ul style={{ padding: '20px', listStyle: 'none', display: 'grid' }}>
<ul style={{ padding: '20px', listStyle: 'none', display: 'grid', gap: '8px' }}>
<li>
<Card>
<Card noMargin>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
</li>
<li>
<Card>
<Card noMargin>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
</li>
<li>
<Card>
<Card noMargin>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
</li>
<li>
<Card>
<Card noMargin>
<Card.Heading>List card item</Card.Heading>
<Card.Description>Card that is rendered inside li element.</Card.Description>
</Card>
@ -161,11 +161,11 @@ export const InsideAListItem: StoryFn<typeof Card> = (args) => {
};
/**
* Cards can also be rendered with media content such icons or images. Such elements need to be wrapped in `Card.Figure` component.
* Cards can also be rendered with media content such as icons or images. Such elements need to be wrapped in `Card.Figure` component.
*/
export const WithMediaElements: StoryFn<typeof Card> = (args) => {
return (
<Card>
<Card noMargin>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
<Card.Figure>
<img src={logo} alt="Grafana Logo" width="40" height="40" />
@ -187,7 +187,7 @@ export const WithMediaElements: StoryFn<typeof Card> = (args) => {
*/
export const ActionCards: StoryFn<typeof Card> = (args) => {
return (
<Card {...args}>
<Card noMargin {...args}>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
<Card.Meta>
Prometheus
@ -220,7 +220,7 @@ export const ActionCards: StoryFn<typeof Card> = (args) => {
*/
export const DisabledState: StoryFn<typeof Card> = (args) => {
return (
<Card disabled>
<Card noMargin disabled>
<Card.Heading>1-ops-tools1-fallback</Card.Heading>
<Card.Meta>
Grafana
@ -249,7 +249,7 @@ export const DisabledState: StoryFn<typeof Card> = (args) => {
export const Selectable: StoryFn<typeof Card> = () => {
return (
<Card isSelected disabled>
<Card noMargin isSelected disabled>
<Card.Heading>Option #1</Card.Heading>
<Card.Description>This is a really great option, you will not regret it.</Card.Description>
<Card.Figure>
@ -261,7 +261,7 @@ export const Selectable: StoryFn<typeof Card> = () => {
export const Full: StoryFn<typeof Card> = (args) => {
return (
<Card {...args}>
<Card noMargin {...args}>
<Card.Heading>Card title</Card.Heading>
<Card.Description>
Description, body text. Greetings! Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod

View File

@ -11,7 +11,7 @@ describe('Card', () => {
const user = userEvent.setup();
const callback = jest.fn();
render(
<Card onClick={callback}>
<Card noMargin onClick={callback}>
<Card.Heading>Test Heading</Card.Heading>
</Card>
);
@ -22,7 +22,7 @@ describe('Card', () => {
describe('Card Actions', () => {
it('Children should be disabled or enabled according to Card disabled prop', () => {
const { rerender } = render(
<Card>
<Card noMargin>
<Card.Heading>Test Heading</Card.Heading>
<Card.Actions>
<Button>Click Me</Button>
@ -37,7 +37,7 @@ describe('Card', () => {
expect(screen.getByRole('button', { name: 'Delete' })).toBeEnabled();
rerender(
<Card disabled>
<Card noMargin disabled>
<Card.Heading>Test Heading</Card.Heading>
<Card.Actions>
<Button>Click Me</Button>
@ -54,7 +54,7 @@ describe('Card', () => {
it('Children should be independently enabled or disabled if explicitly set', () => {
const { rerender } = render(
<Card>
<Card noMargin>
<Card.Heading>Test Heading</Card.Heading>
<Card.Actions>
<Button disabled>Click Me</Button>
@ -69,7 +69,7 @@ describe('Card', () => {
expect(screen.getByRole('button', { name: 'Delete' })).toBeDisabled();
rerender(
<Card disabled>
<Card noMargin disabled>
<Card.Heading>Test Heading</Card.Heading>
<Card.Actions>
<Button disabled={false}>Click Me</Button>
@ -87,7 +87,7 @@ describe('Card', () => {
it('Children should be conditional', () => {
const shouldNotRender = false;
render(
<Card>
<Card noMargin>
<Card.Heading>Test Heading</Card.Heading>
<Card.Actions>
<Button>Click Me</Button>
@ -105,7 +105,7 @@ describe('Card', () => {
it('Should allow selectable cards', () => {
const { rerender } = render(
<Card isSelected={true}>
<Card noMargin isSelected={true}>
<Card.Heading>My Option</Card.Heading>
</Card>
);
@ -114,7 +114,7 @@ describe('Card', () => {
expect(screen.getByRole('radio')).toBeChecked();
rerender(
<Card isSelected={false}>
<Card noMargin isSelected={false}>
<Card.Heading>My Option</Card.Heading>
</Card>
);
@ -123,7 +123,7 @@ describe('Card', () => {
expect(screen.getByRole('radio')).not.toBeChecked();
rerender(
<Card>
<Card noMargin>
<Card.Heading>My Option</Card.Heading>
</Card>
);

View File

@ -226,7 +226,7 @@ export const ThemeDemo = () => {
Disabled
</Button>
</Stack>
<Card>
<Card noMargin>
<Card.Heading>Button inside card</Card.Heading>
<Card.Actions>
{allButtonVariants.map((variant) => (
@ -259,8 +259,8 @@ export function VizHuesDemo({ theme, color }: VizHuesDemoProps) {
return (
<tr>
<td>{color.name}</td>
{color.shades.map((shade) => (
<td>
{color.shades.map((shade, index) => (
<td key={index}>
<div
className={css({
background: shade.color,