UNPKG

vui-design

Version:

A high quality UI Toolkit based on Vue.js

205 lines (178 loc) 5.18 kB
import VuiIcon from "../icon"; import VuiRow from "../row"; import VuiCol from "../col"; import PropTypes from "../../utils/prop-types"; import getValidElements from "../../utils/getValidElements"; import getClassNamePrefix from "../../utils/getClassNamePrefix"; const gridCardLoadingBlocks = [ [20], [8, 16], [4, 18], [12, 8], [8, 8, 8] ]; export const createProps = () => { return { classNamePrefix: PropTypes.string, icon: PropTypes.string, title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), extra: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), cover: PropTypes.string, bordered: PropTypes.bool.def(true), shadow: PropTypes.oneOf(["never", "hover", "always"]).def("never"), headerStyle: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), bodyStyle: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), footerStyle: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), loading: PropTypes.bool.def(false) }; }; export default { name: "vui-card", components: { VuiIcon, VuiRow, VuiCol }, props: createProps(), methods: { withCardGrids(children = [], tagName = "vui-card-grid") { return children.some(node => node && node.componentOptions && node.componentOptions.tag === tagName); } }, render(h) { const { $slots: slots, $props: props } = this; const withCardGrids = this.withCardGrids(slots.default); // icon let icon; if (slots.icon) { icon = slots.icon; } else if (props.icon) { icon = ( <VuiIcon type={props.icon} /> ); } // title const title = slots.title || props.title; // extra const extra = slots.extra || props.extra; // cover let cover; if (slots.cover) { cover = slots.cover; } else if (props.cover) { cover = ( <img src={props.cover} /> ); } // class const classNamePrefix = getClassNamePrefix(props.classNamePrefix, "card"); let classes = {}; classes.el = { [`${classNamePrefix}`]: true, [`${classNamePrefix}-bordered`]: props.bordered, [`${classNamePrefix}-shadow-${props.shadow}`]: props.shadow, [`${classNamePrefix}-with-grid`]: withCardGrids }; classes.elHeader = `${classNamePrefix}-header`; classes.elIcon = `${classNamePrefix}-icon`; classes.elTitle = `${classNamePrefix}-title`; classes.elExtra = `${classNamePrefix}-extra`; classes.elCover = `${classNamePrefix}-cover`; classes.elBody = `${classNamePrefix}-body`; classes.elLoading = `${classNamePrefix}-loading`; classes.elLoadingRow = `${classNamePrefix}-loading-row`; classes.elLoadingBlock = `${classNamePrefix}-loading-block`; classes.elActions = `${classNamePrefix}-actions`; classes.elAction = `${classNamePrefix}-action`; classes.elActionDivider = `${classNamePrefix}-action-divider`; classes.elFooter = `${classNamePrefix}-footer`; // render let children = []; if (icon || title || extra) { let header = []; if (icon) { header.push( <div class={classes.elIcon}>{icon}</div> ); } if (title) { header.push( <div class={classes.elTitle}>{title}</div> ); } if (extra) { header.push( <div class={classes.elExtra}>{extra}</div> ); } children.push( <div class={classes.elHeader} style={props.headerStyle}>{header}</div> ); } if (cover) { children.push( <div class={classes.elCover}>{cover}</div> ); } let body; if (!props.loading) { body = slots.default; } else if (slots.loading) { body = slots.loading; } else { body = ( <div class={classes.elLoading}> { gridCardLoadingBlocks.map(row => { return ( <VuiRow gutter={8} class={classes.elLoadingRow}> { row.map(col => { return ( <VuiCol span={col}> <div class={classes.elLoadingBlock}></div> </VuiCol> ); }) } </VuiRow> ); }) } </div> ); } children.push( <div class={classes.elBody} style={props.bodyStyle}>{body}</div> ); if (slots.actions) { const elements = getValidElements(slots.actions); let actions = []; elements.forEach((element, index) => { if (index > 0) { actions.push( <i class={classes.elActionDivider} /> ); } actions.push( <div class={classes.elAction}>{element}</div> ); }); children.push( <div class={classes.elActions}>{actions}</div> ); } if (slots.footer) { children.push( <div class={classes.elFooter} style={props.footerStyle}>{slots.footer}</div> ); } return ( <div class={classes.el}>{children}</div> ); } };