index.tsx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import React, { PureComponent } from 'react';
  2. import cls from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import { strings, cssClasses } from '@douyinfe/semi-foundation/descriptions/constants';
  5. import '@douyinfe/semi-foundation/descriptions/descriptions.scss';
  6. import { isPlainObject } from 'lodash';
  7. import DescriptionsContext, { DescriptionsAlign, DescriptionsContextValue } from './descriptions-context';
  8. import Item from './item';
  9. export { DescriptionsItemProps } from './item';
  10. export type DescriptionsSize = 'small' | 'medium' | 'large';
  11. export interface Data {
  12. [x: string]: any;
  13. key?: string | number;
  14. value?: (() => React.ReactNode) | React.ReactNode;
  15. hidden?: boolean;
  16. }
  17. export interface DescriptionsProps {
  18. align?: DescriptionsAlign;
  19. row?: boolean;
  20. size?: DescriptionsSize;
  21. style?: React.CSSProperties;
  22. className?: string;
  23. children?: React.ReactNode | undefined;
  24. data?: Data[];
  25. }
  26. const prefixCls = cssClasses.PREFIX;
  27. class Descriptions extends PureComponent<DescriptionsProps> {
  28. static Item = Item;
  29. static contextType = DescriptionsContext;
  30. static propTypes = {
  31. align: PropTypes.oneOf(strings.ALIGN_SET),
  32. row: PropTypes.bool,
  33. size: PropTypes.oneOf(strings.SIZE_SET),
  34. style: PropTypes.object,
  35. className: PropTypes.string,
  36. data: PropTypes.arrayOf(PropTypes.shape({
  37. key: PropTypes.node,
  38. value: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
  39. hidden: PropTypes.bool,
  40. className: PropTypes.string,
  41. style: PropTypes.object
  42. })),
  43. };
  44. static defaultProps = {
  45. align: 'center',
  46. row: false,
  47. size: 'medium',
  48. data: [] as Array<Data>,
  49. };
  50. render() {
  51. const { align, row, size, className, style, children, data } = this.props;
  52. const classNames = cls(prefixCls, className, {
  53. [`${prefixCls}-${align}`]: !row,
  54. [`${prefixCls}-double`]: row,
  55. [`${prefixCls}-double-${size}`]: row,
  56. });
  57. const childrenList = data && data.length ?
  58. data.map(item => (
  59. isPlainObject(item) ? <Item key={item.key} itemKey={item.key} {...item}>{item.value}</Item> : null
  60. )) :
  61. children;
  62. return (
  63. <div className={classNames} style={style}>
  64. <table>
  65. <tbody>
  66. <DescriptionsContext.Provider value={{ align }}>
  67. {childrenList}
  68. </DescriptionsContext.Provider>
  69. </tbody>
  70. </table>
  71. </div>
  72. );
  73. }
  74. }
  75. export default Descriptions;