Skip to content

Commit

Permalink
feat: improve docs for Card with renderImage prop
Browse files Browse the repository at this point in the history
chore: add tests for Card
  • Loading branch information
levino committed May 4, 2023
1 parent 12d9a26 commit 153669f
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const decorators = [
];

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
actions: { argTypesRegex: '^on[A-Z].*', argTypesRegex: '^render[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
Expand Down
69 changes: 31 additions & 38 deletions src/lib/components/Card/Card.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,37 @@ import { Flowbite } from '../Flowbite';
import { Card } from './Card';

describe('Components / Card', () => {
describe('Functionality', () => {
it('should render an image when `imgSrc` is provided', () => {
render(<Card imgSrc="https://flowbite.com/docs/images/blog/image-1.jpg" />);
expect(screen.queryAllByTestId('flowbite-card-image')).toHaveLength(1);
expect(screen.queryByTestId('flowbite-card-image')).toHaveAttribute(
'src',
'https://flowbite.com/docs/images/blog/image-1.jpg',
);
});
it('should not render an `<img>` given an undefined `imgSrc`', () => {
render(<Card imgSrc={undefined} />);
expect(screen.queryAllByTestId('flowbite-card-image')).toHaveLength(0);
});

it('should render the image from the `renderImage` prop', () => {
render(<Card renderImage={() => <div data-testId="dummy-div" />} />);

expect(screen.queryAllByTestId('dummy-div')).toHaveLength(1);
});
it('should use the `renderImage` prop even if the user provides an `imgSrc`', () => {
render(
/* @ts-expect-error should be illegal to use `renderImage` and `imgSrc` at the same time */
<Card
renderImage={() => <div data-testId="dummy-div2" />}
imgSrc="https://flowbite.com/docs/images/blog/image-1.jpg"
/>,
);
expect(screen.queryAllByTestId('dummy-div2')).toHaveLength(1);
expect(screen.queryAllByTestId('flowbite-card-image')).toHaveLength(0);
});
});
describe('A11y', () => {
it('should allow `aria-label`', () => {
render(<Card aria-label="My card" />);
Expand Down Expand Up @@ -146,44 +177,6 @@ describe('Components / Card', () => {
expect(cardWithImage).toHaveClass('text-blue-400 bg-blue-500');
expect(horizontalCardWithImage).toHaveClass('bg-blue-600');
});
it('should render the image from the `renderImage` prop', () => {
const theme = {
card: {
img: {
base: 'text-blue-400',
horizontal: {
off: 'bg-blue-500',
on: 'bg-blue-600',
},
},
},
};
const component = render(
<Flowbite theme={{ theme }}>
<Card renderImage={() => <img src="https://flowbite.com/docs/images/blog/image-1.jpg" />} />
</Flowbite>,
);

const image1 = component.getByRole('img');

expect(image1).toHaveProperty('src', 'https://flowbite.com/docs/images/blog/image-1.jpg');

component.unmount();

const component2 = render(
<Flowbite theme={{ theme }}>
{/* @ts-expect-error should be illegal to use `renderImage` and `imgSrc` at the same time */}
<Card
renderImage={() => <img src="https://flowbite.com/docs/images/blog/image-2.jpg" />}
imgSrc="https://flowbite.com/docs/images/blog/image-1.jpg"
/>
</Flowbite>,
);

const image2 = component2.getByRole('img');

expect(image2).toHaveProperty('src', 'https://flowbite.com/docs/images/blog/image-2.jpg');
});
});
});

Expand Down
8 changes: 1 addition & 7 deletions src/lib/components/Card/Card.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ import { Card } from './Card';
export default {
title: 'Components/Card',
component: Card,
decorators: [
(Story): JSX.Element => (
<div className="h-1/2 w-1/2">
<Story />
</div>
),
],
decorators: [(Story): JSX.Element => <div className="h-1/2 w-1/2">{Story()}</div>],
} as Meta;

const Template: Story<CardProps> = (args) => (
Expand Down
6 changes: 6 additions & 0 deletions src/lib/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,18 @@ export interface FlowbiteCardImageTheme {
interface CommonCardProps extends PropsWithChildren<ComponentProps<'div'>> {
horizontal?: boolean;
href?: string;
/** Overwrites the theme. Will be merged with the context theme.
* @default {}
*/
theme?: DeepPartial<FlowbiteCardTheme>;
}

export type CardProps =
| (
| { imgAlt?: string; imgSrc?: string; renderImage?: never }
| {
/** Allows to provide a custom render function for the image component. Useful in Next.JS and Gatsby. **Setting this will disable `imgSrc` and `imgAlt`**.
*/
renderImage?: () => JSX.Element;
imgAlt?: never;
imgSrc?: never;
Expand Down Expand Up @@ -73,6 +78,7 @@ const Image: FC<CardProps> = ({ theme: customTheme = {}, ...props }) => {
if (props.imgSrc) {
return (
<img
data-testid="flowbite-card-image"
alt={props.imgAlt ?? ''}
src={props.imgSrc}
className={classNames(theme.img.base, theme.img.horizontal[props.horizontal ? 'on' : 'off'])}
Expand Down

0 comments on commit 153669f

Please sign in to comment.