diff --git a/src/Card/BaseCard.jsx b/src/Card/BaseCard.tsx similarity index 70% rename from src/Card/BaseCard.jsx rename to src/Card/BaseCard.tsx index 088cb5aae1..0c0723d69c 100644 --- a/src/Card/BaseCard.jsx +++ b/src/Card/BaseCard.tsx @@ -2,11 +2,43 @@ import React from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; +import type { ComponentWithAsProp, BsPropsWithAs } from '../utils/types/bootstrap'; + +// @ts-ignore import CardBody from './CardBody'; const BASE_CARD_CLASSNAME = 'card'; -const BaseCard = React.forwardRef( +const colorVariants = [ + 'primary', + 'secondary', + 'success', + 'danger', + 'warning', + 'info', + 'dark', + 'light', +] as const; + +const textVariants = [ + 'white', + 'muted', +] as const; + +type ColorVariant = typeof colorVariants[number]; +type TextVariant = typeof textVariants[number]; +interface Props extends BsPropsWithAs { + prefix?: string; + bgColor?: ColorVariant; + textColor?: ColorVariant | TextVariant; + borderColor?: ColorVariant; + hasBody?: boolean; + className?: string; + children: React.ReactNode; +} +type BaseCardType = ComponentWithAsProp<'div', Props>; + +const BaseCard : BaseCardType = React.forwardRef( ( { prefix, @@ -14,9 +46,9 @@ const BaseCard = React.forwardRef( bgColor, textColor, borderColor, - hasBody, + hasBody = false, children, - as: Component, + as: Component = 'div', ...props }, ref, @@ -37,24 +69,13 @@ const BaseCard = React.forwardRef( }, ); -const colorVariants = [ - 'primary', - 'secondary', - 'success', - 'danger', - 'warning', - 'info', - 'dark', - 'light', -]; - BaseCard.propTypes = { /** Prefix for component CSS classes. */ prefix: PropTypes.string, /** Background color of the card. */ bgColor: PropTypes.oneOf(colorVariants), /** Text color of the card. */ - textColor: PropTypes.oneOf([...colorVariants, 'white', 'muted']), + textColor: PropTypes.oneOf([...colorVariants, ...textVariants]), /** Border color of the card. */ borderColor: PropTypes.oneOf(colorVariants), /** Determines whether the card should render its children inside a `CardBody` wrapper. */ diff --git a/src/Card/tests/BaseCard.test.jsx b/src/Card/tests/BaseCard.test.jsx index e555793191..c820ccf689 100644 --- a/src/Card/tests/BaseCard.test.jsx +++ b/src/Card/tests/BaseCard.test.jsx @@ -41,6 +41,17 @@ describe('BaseCard Component', () => { }); it('renders children directly when hasBody is false', () => { + render( + + Direct Content + , + ); + const contentElement = screen.getByText('Direct Content'); + expect(contentElement).toBeInTheDocument(); + expect(contentElement.closest('div')).not.toHaveClass('card-body'); + }); + + it('renders children directly when hasBody isn\'t set', () => { render( Direct Content