import React, { Component, Children } from 'react'; import classNames from 'classnames'; import addEventListener, { RcUtilEventHandler } from 'rc-util/lib/Dom/addEventListener'; import Grid from './Grid'; import { throttleByAnimationFrameDecorator } from '../_util/throttleByAnimationFrame'; export interface CardProps { prefixCls?: string; title?: React.ReactNode; extra?: React.ReactNode; bordered?: boolean; bodyStyle?: React.CSSProperties; style?: React.CSSProperties; loading?: boolean; noHovering?: boolean; children?: React.ReactChild; id?: string; className?: string; } export default class Card extends Component { static Grid: typeof Grid = Grid; container: HTMLDivElement; resizeEvent: RcUtilEventHandler; updateWiderPaddingCalled: boolean; state = { widerPadding: false, }; componentDidMount() { this.updateWiderPadding(); this.resizeEvent = addEventListener(window, 'resize', this.updateWiderPadding); } componentWillUnmount() { if (this.resizeEvent) { this.resizeEvent.remove(); } (this.updateWiderPadding as any).cancel(); } @throttleByAnimationFrameDecorator() updateWiderPadding() { if (!this.container) { return; } // 936 is a magic card width pixer number indicated by designer const WIDTH_BOUDARY_PX = 936; if (this.container.offsetWidth >= WIDTH_BOUDARY_PX && !this.state.widerPadding) { this.setState({ widerPadding: true }, () => { this.updateWiderPaddingCalled = true; // first render without css transition }); } if (this.container.offsetWidth < WIDTH_BOUDARY_PX && this.state.widerPadding) { this.setState({ widerPadding: false }, () => { this.updateWiderPaddingCalled = true; // first render without css transition }); } } saveRef = (node: HTMLDivElement) => { this.container = node; } isContainGrid() { let containGrid; Children.forEach(this.props.children, (element: JSX.Element) => { if (element && element.type && element.type === Grid) { containGrid = true; } }); return containGrid; } render() { const { prefixCls = 'ant-card', className, extra, bodyStyle, noHovering, title, loading, bordered = true, ...others, } = this.props; let children = this.props.children; const classString = classNames(prefixCls, className, { [`${prefixCls}-loading`]: loading, [`${prefixCls}-bordered`]: bordered, [`${prefixCls}-no-hovering`]: noHovering, [`${prefixCls}-wider-padding`]: this.state.widerPadding, [`${prefixCls}-padding-transition`]: this.updateWiderPaddingCalled, [`${prefixCls}-contain-grid`]: this.isContainGrid(), }); if (loading) { children = (

); } let head; if (!title) { head = null; } else { head = typeof title === 'string' ? (

{title}

) : (
{title}
); } return (
{head} {extra ?
{extra}
: null}
{children}
); } }