chore: initial deploy for code base
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
import * as React from "react";
|
||||
import { Card as AntCard } from "antd";
|
||||
import Loader from "../loader/Loader";
|
||||
import Spacing from "../spacing/Spacing";
|
||||
import Text from '../text/Text';
|
||||
import Image from '../image/Image';
|
||||
import Link from '../link/Link';
|
||||
import CheckCircleIcon from "../icon/CheckCircleIcon";
|
||||
import WarningIcon from "../icon/WarningIcon";
|
||||
import IIconProps from "../icon/IIconProps";
|
||||
import WarningCircleIcon from "../icon/WarningCircleIcon";
|
||||
|
||||
export interface ICardProps {
|
||||
/** Card title */
|
||||
title?: React.ReactNode;
|
||||
|
||||
/** Title icon */
|
||||
icon?: React.ReactElement<IIconProps>;
|
||||
|
||||
/** Card type. Default is "normal." "success", "attention", and "error" override the icon prop */
|
||||
type?: "normal" | "success" | "error" | "attention";
|
||||
|
||||
/** Card description below the title */
|
||||
description?: string;
|
||||
|
||||
/** Content to the right of the card title */
|
||||
extra?: React.ReactNode;
|
||||
|
||||
/** Cover image src. Cannot be used with title */
|
||||
image?: string;
|
||||
|
||||
/** Card footer. Requires children to be set */
|
||||
footer?: React.ReactNode;
|
||||
|
||||
/** Remove body padding */
|
||||
removeBodyPadding?: boolean;
|
||||
|
||||
/** Min height of the card, excluding the height of the title or image */
|
||||
height?: number | string;
|
||||
|
||||
/** Trigger an action on card click. Cannot be used with href */
|
||||
onClick?: () => void;
|
||||
|
||||
/** Trigger a link on card click. Cannot be used with onClick */
|
||||
href?: string;
|
||||
|
||||
/** Show loading mask */
|
||||
loading?: boolean;
|
||||
|
||||
/** Add selected style */
|
||||
selected?: boolean;
|
||||
}
|
||||
|
||||
/** Cards structure content like text, forms, and tables. */
|
||||
const Card: React.FC<ICardProps> = (props) => {
|
||||
const { removeBodyPadding, loading, selected, type, image, description, height, onClick, href, ...validProps } = props;
|
||||
|
||||
let className = "tempo-card";
|
||||
if (removeBodyPadding || !validProps.children) {
|
||||
className += " tempo-card--body-no-padding";
|
||||
}
|
||||
if (selected) {
|
||||
className += " tempo-card--selected"
|
||||
}
|
||||
|
||||
let title = validProps.title;
|
||||
if (title) {
|
||||
title = <Text.Heading level={3}>{title}</Text.Heading>;
|
||||
|
||||
if (description) {
|
||||
title = (
|
||||
<Spacing column padding={"12px 0"}>
|
||||
{title}
|
||||
<Text color="secondary">{description}</Text>
|
||||
</Spacing>
|
||||
);
|
||||
}
|
||||
|
||||
let icon: React.ReactElement<IIconProps> | null = null;
|
||||
|
||||
if (props.icon) {
|
||||
icon = React.cloneElement(props.icon, {
|
||||
size: props.icon.props.size || 20,
|
||||
});
|
||||
}
|
||||
|
||||
if (type === "success") {
|
||||
icon = <CheckCircleIcon color='success' size={20} />
|
||||
} else if (type === "error") {
|
||||
icon = <WarningIcon color='error' size={20} />;
|
||||
}
|
||||
else if (type === "attention") {
|
||||
icon = <WarningCircleIcon color='attention' size={20} />;
|
||||
}
|
||||
|
||||
if (icon != null) {
|
||||
title = (
|
||||
<Spacing vAlign="center" itemSpacing={8}>
|
||||
{icon}
|
||||
{title}
|
||||
</Spacing>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let extra = validProps.extra;
|
||||
|
||||
let cover;
|
||||
if (!title && image) {
|
||||
cover = <Image src={image} height={180} border="bottom" backgroundColor="#F5F5F5" />;
|
||||
}
|
||||
|
||||
let contents = validProps.children;
|
||||
if (contents) {
|
||||
contents = <div style={{ minHeight: height }}>{contents}</div>;
|
||||
|
||||
if (validProps.footer) {
|
||||
contents = (
|
||||
<div className="tempo-card-contents-and-footer" style={{ minHeight: height }}>
|
||||
<div>{validProps.children}</div>
|
||||
<div className="tempo-card-footer">{validProps.footer}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let tabIndex, onKeyPress;
|
||||
if (onClick && !loading) {
|
||||
tabIndex = 0;
|
||||
|
||||
onKeyPress = (e: React.KeyboardEvent<HTMLDivElement>) => {
|
||||
e.key === 'Enter' && onClick();
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(validProps, {
|
||||
hoverable: props.onClick || href
|
||||
});
|
||||
|
||||
const card = <AntCard {...validProps}
|
||||
onClick={onClick}
|
||||
onKeyPress={onKeyPress}
|
||||
tabIndex={tabIndex}
|
||||
title={title}
|
||||
extra={extra}
|
||||
cover={cover}
|
||||
className={className}>{contents}</AntCard>;
|
||||
|
||||
return (
|
||||
<Loader loading={loading}>
|
||||
{href ? <Link href={href}>{card}</Link> : card}
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
export default Card;
|
||||
Reference in New Issue
Block a user