diff --git a/src/components/card/CardBody.tsx b/src/components/card/CardBody.tsx index 89c0061bc..4073daab2 100644 --- a/src/components/card/CardBody.tsx +++ b/src/components/card/CardBody.tsx @@ -38,12 +38,7 @@ export const CardBody = React.forwardRef } return ( - + {children} ); diff --git a/src/components/card/CardHeader.tsx b/src/components/card/CardHeader.tsx index 06c1dc49e..e60ecf602 100644 --- a/src/components/card/CardHeader.tsx +++ b/src/components/card/CardHeader.tsx @@ -120,7 +120,7 @@ export const CardHeader = React.forwardRef {isFullyCollapsible ? ( ` +export const CardHeaderStyled = styled.header<{ disablePadding: boolean }>` align-items: center; display: flex; - min-height: var(--card-header-min-height); - ${({ noPadding }) => (noPadding ? '' : 'padding: var(--card-header-padding);')} + ${({ disablePadding }) => (disablePadding ? '' : 'padding: var(--card-header-padding);')} `; CardHeaderStyled.displayName = 'CardHeaderStyled'; @@ -66,7 +65,6 @@ export const RightContentStyled = styled.div` align-items: center; display: flex; gap: ${cssVar('dimension-space-100')}; - max-height: var(--card-header-heading-height); `; RightContentStyled.displayName = 'RightContentStyled'; @@ -86,7 +84,9 @@ export const CardHeaderTitleButtonStyled = styled(ButtonStyled)` display: flex; flex-direction: row; flex: 1; - min-height: var(--card-header-min-height); + /* ButtonStyled sets fixed dimensions; this header button sizes from padding instead. */ + height: auto; + min-height: auto; padding: var(--card-header-padding); border-bottom-right-radius: 0; @@ -94,9 +94,8 @@ export const CardHeaderTitleButtonStyled = styled(ButtonStyled)` `; CardHeaderTitleButtonStyled.displayName = 'CardHeaderTitleButtonStyled'; -export const CardBodyStyled = styled.div<{ size: `${CardSize}`; insetContent: boolean }>` +export const CardBodyStyled = styled.div<{ insetContent: boolean }>` box-sizing: border-box; - min-height: var(--card-body-min-height); padding: ${(props) => (props.insetContent ? '0' : 'var(--card-padding)')}; width: 100%; @@ -108,33 +107,24 @@ CardBodyStyled.displayName = 'CardBodyStyled'; export const CARD_HEADER_SIZE_STYLES = { [CardSize.Large]: { - '--card-header-heading-height': '1.875rem', - '--card-header-min-height': '58px', - '--card-header-padding': `${cssVar('dimension-space-200')} ${cssVar('dimension-space-300')}`, + '--card-header-padding': `${cssVar('dimension-space-250')} ${cssVar('dimension-space-300')}`, }, [CardSize.Medium]: { - '--card-header-heading-height': '1.5rem', - '--card-header-min-height': '45px', '--card-header-padding': `${cssVar('dimension-space-150')} ${cssVar('dimension-space-200')}`, }, [CardSize.Small]: { - '--card-header-heading-height': '1.25rem', - '--card-header-min-height': '36px', '--card-header-padding': `${cssVar('dimension-space-100')} ${cssVar('dimension-space-150')}`, }, }; export const CARD_SIZE_STYLES = { [CardSize.Large]: { - '--card-body-min-height': '108px', '--card-padding': cssVar('dimension-space-300'), }, [CardSize.Medium]: { - '--card-body-min-height': '92px', '--card-padding': cssVar('dimension-space-200'), }, [CardSize.Small]: { - '--card-body-min-height': '84px', '--card-padding': cssVar('dimension-space-150'), }, }; diff --git a/src/components/card/__tests__/Card-test.tsx b/src/components/card/__tests__/Card-test.tsx index 428953489..d7350efc9 100644 --- a/src/components/card/__tests__/Card-test.tsx +++ b/src/components/card/__tests__/Card-test.tsx @@ -27,6 +27,7 @@ import { CardBody } from '../CardBody'; import { CardHeader } from '../CardHeader'; import { CardRoot } from '../CardRoot'; import { CardSize } from '../CardSize'; +import { CARD_HEADER_SIZE_STYLES, CARD_SIZE_STYLES } from '../CardStyles'; describe('Card components', () => { describe('CardRoot', () => { @@ -90,6 +91,35 @@ describe('Card components', () => { expect(screen.getByRole('button', { name: 'Action' })).toBeInTheDocument(); }); + it('defines header and body size through padding only', () => { + expect(CARD_HEADER_SIZE_STYLES).toEqual({ + [CardSize.Large]: { + '--card-header-padding': + 'var(--echoes-dimension-space-250) var(--echoes-dimension-space-300)', + }, + [CardSize.Medium]: { + '--card-header-padding': + 'var(--echoes-dimension-space-150) var(--echoes-dimension-space-200)', + }, + [CardSize.Small]: { + '--card-header-padding': + 'var(--echoes-dimension-space-100) var(--echoes-dimension-space-150)', + }, + }); + + expect(CARD_SIZE_STYLES).toEqual({ + [CardSize.Large]: { + '--card-padding': 'var(--echoes-dimension-space-300)', + }, + [CardSize.Medium]: { + '--card-padding': 'var(--echoes-dimension-space-200)', + }, + [CardSize.Small]: { + '--card-padding': 'var(--echoes-dimension-space-150)', + }, + }); + }); + it('uses correct heading level based on card size', () => { const { rerender } = render( @@ -149,6 +179,7 @@ describe('Card components', () => { ); expect(ref.current).not.toBeNull(); + expect(ref.current).not.toHaveAttribute('size'); }); it('applies insetContent prop correctly', () => { @@ -248,6 +279,20 @@ describe('Card components', () => { expect(screen.getByRole('button', { name: 'Collapse' })).toBeInTheDocument(); }); + it('does not apply a minimum height to the collapsible header button', () => { + render( + + + + Card Content + , + ); + + expect( + window.getComputedStyle(screen.getByRole('button', { name: 'Collapse' })).minHeight, + ).toBe('auto'); + }); + it('does not render a toggle button when isCollapsible is false', () => { render(