index.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. import _defineProperty from 'babel-runtime/helpers/defineProperty';
  2. import _typeof from 'babel-runtime/helpers/typeof';
  3. import warning from '../_util/warning';
  4. import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
  5. import { ConfigConsumerProps } from '../config-provider/configConsumerProps';
  6. import Col from './Col';
  7. import PropTypes from '../_util/vue-types';
  8. import { initDefaultProps, isValidElement, getOptionProps, getComponentFromProp } from '../_util/props-util';
  9. import BaseMixin from '../_util/BaseMixin';
  10. import Base from '../base';
  11. import { cloneElement } from '../_util/vnode';
  12. export var DescriptionsItemProps = {
  13. prefixCls: PropTypes.string,
  14. label: PropTypes.any,
  15. span: PropTypes.number
  16. };
  17. function toArray(value) {
  18. var ret = value;
  19. if (value === undefined) {
  20. ret = [];
  21. } else if (!Array.isArray(value)) {
  22. ret = [value];
  23. }
  24. return ret;
  25. }
  26. export var DescriptionsItem = {
  27. name: 'ADescriptionsItem',
  28. props: initDefaultProps(DescriptionsItemProps, { span: 1 })
  29. };
  30. export var DescriptionsProps = {
  31. prefixCls: PropTypes.string,
  32. bordered: PropTypes.bool,
  33. size: PropTypes.oneOf(['default', 'middle', 'small']).def('default'),
  34. title: PropTypes.any,
  35. column: PropTypes.oneOfType([PropTypes.number, PropTypes.object]),
  36. layout: PropTypes.oneOf(['horizontal', 'vertical']),
  37. colon: PropTypes.bool
  38. };
  39. /**
  40. * Convert children into `column` groups.
  41. * @param children: DescriptionsItem
  42. * @param column: number
  43. */
  44. var generateChildrenRows = function generateChildrenRows(children, column) {
  45. var rows = [];
  46. var columns = null;
  47. var leftSpans = void 0;
  48. var itemNodes = toArray(children);
  49. itemNodes.forEach(function (node, index) {
  50. var itemProps = getOptionProps(node);
  51. var itemNode = node;
  52. if (!columns) {
  53. leftSpans = column;
  54. columns = [];
  55. rows.push(columns);
  56. }
  57. // Always set last span to align the end of Descriptions
  58. var lastItem = index === itemNodes.length - 1;
  59. var lastSpanSame = true;
  60. if (lastItem) {
  61. lastSpanSame = !itemProps.span || itemProps.span === leftSpans;
  62. itemNode = cloneElement(itemNode, {
  63. props: {
  64. span: leftSpans
  65. }
  66. });
  67. }
  68. // Calculate left fill span
  69. var _itemProps$span = itemProps.span,
  70. span = _itemProps$span === undefined ? 1 : _itemProps$span;
  71. columns.push(itemNode);
  72. leftSpans -= span;
  73. if (leftSpans <= 0) {
  74. columns = null;
  75. warning(leftSpans === 0 && lastSpanSame, 'Descriptions', 'Sum of column `span` in a line exceeds `column` of Descriptions.');
  76. }
  77. });
  78. return rows;
  79. };
  80. var defaultColumnMap = {
  81. xxl: 3,
  82. xl: 3,
  83. lg: 3,
  84. md: 3,
  85. sm: 2,
  86. xs: 1
  87. };
  88. var Descriptions = {
  89. name: 'ADescriptions',
  90. Item: DescriptionsItem,
  91. mixins: [BaseMixin],
  92. inject: {
  93. configProvider: { 'default': function _default() {
  94. return ConfigConsumerProps;
  95. } }
  96. },
  97. props: initDefaultProps(DescriptionsProps, {
  98. column: defaultColumnMap
  99. }),
  100. data: function data() {
  101. return {
  102. screens: {},
  103. token: undefined
  104. };
  105. },
  106. methods: {
  107. getColumn: function getColumn() {
  108. var column = this.$props.column;
  109. if ((typeof column === 'undefined' ? 'undefined' : _typeof(column)) === 'object') {
  110. for (var i = 0; i < responsiveArray.length; i++) {
  111. var breakpoint = responsiveArray[i];
  112. if (this.screens[breakpoint] && column[breakpoint] !== undefined) {
  113. return column[breakpoint] || defaultColumnMap[breakpoint];
  114. }
  115. }
  116. }
  117. // If the configuration is not an object, it is a number, return number
  118. if (typeof column === 'number') {
  119. return column;
  120. }
  121. // If it is an object, but no response is found, this happens only in the test.
  122. // Maybe there are some strange environments
  123. return 3;
  124. },
  125. renderRow: function renderRow(children, index, _ref, bordered, layout, colon) {
  126. var prefixCls = _ref.prefixCls;
  127. var h = this.$createElement;
  128. var renderCol = function renderCol(colItem, type, idx) {
  129. return h(Col, {
  130. attrs: {
  131. child: colItem,
  132. bordered: bordered,
  133. colon: colon,
  134. type: type,
  135. layout: layout
  136. },
  137. key: type + '-' + (colItem.key || idx) });
  138. };
  139. var cloneChildren = [];
  140. var cloneContentChildren = [];
  141. toArray(children).forEach(function (childrenItem, idx) {
  142. cloneChildren.push(renderCol(childrenItem, 'label', idx));
  143. if (layout === 'vertical') {
  144. cloneContentChildren.push(renderCol(childrenItem, 'content', idx));
  145. } else if (bordered) {
  146. cloneChildren.push(renderCol(childrenItem, 'content', idx));
  147. }
  148. });
  149. if (layout === 'vertical') {
  150. return [h(
  151. 'tr',
  152. { 'class': prefixCls + '-row', key: 'label-' + index },
  153. [cloneChildren]
  154. ), h(
  155. 'tr',
  156. { 'class': prefixCls + '-row', key: 'content-' + index },
  157. [cloneContentChildren]
  158. )];
  159. }
  160. return h(
  161. 'tr',
  162. { 'class': prefixCls + '-row', key: index },
  163. [cloneChildren]
  164. );
  165. }
  166. },
  167. mounted: function mounted() {
  168. var _this = this;
  169. var column = this.$props.column;
  170. this.token = ResponsiveObserve.subscribe(function (screens) {
  171. if ((typeof column === 'undefined' ? 'undefined' : _typeof(column)) !== 'object') {
  172. return;
  173. }
  174. _this.setState({
  175. screens: screens
  176. });
  177. });
  178. },
  179. beforeDestroy: function beforeDestroy() {
  180. ResponsiveObserve.unsubscribe(this.token);
  181. },
  182. render: function render() {
  183. var _ref2,
  184. _this2 = this;
  185. var h = arguments[0];
  186. var _$props = this.$props,
  187. customizePrefixCls = _$props.prefixCls,
  188. size = _$props.size,
  189. _$props$bordered = _$props.bordered,
  190. bordered = _$props$bordered === undefined ? false : _$props$bordered,
  191. _$props$layout = _$props.layout,
  192. layout = _$props$layout === undefined ? 'horizontal' : _$props$layout,
  193. _$props$colon = _$props.colon,
  194. colon = _$props$colon === undefined ? true : _$props$colon;
  195. var title = getComponentFromProp(this, 'title') || null;
  196. var getPrefixCls = this.configProvider.getPrefixCls;
  197. var prefixCls = getPrefixCls('descriptions', customizePrefixCls);
  198. var column = this.getColumn();
  199. var children = this.$slots['default'];
  200. var cloneChildren = toArray(children).map(function (child) {
  201. if (isValidElement(child)) {
  202. return cloneElement(child, {
  203. props: {
  204. prefixCls: prefixCls
  205. }
  206. });
  207. }
  208. return null;
  209. }).filter(function (node) {
  210. return node;
  211. });
  212. var childrenArray = generateChildrenRows(cloneChildren, column);
  213. return h(
  214. 'div',
  215. {
  216. 'class': [prefixCls, (_ref2 = {}, _defineProperty(_ref2, prefixCls + '-' + size, size !== 'default'), _defineProperty(_ref2, prefixCls + '-bordered', !!bordered), _ref2)]
  217. },
  218. [title && h(
  219. 'div',
  220. { 'class': prefixCls + '-title' },
  221. [title]
  222. ), h(
  223. 'div',
  224. { 'class': prefixCls + '-view' },
  225. [h('table', [h('tbody', [childrenArray.map(function (child, index) {
  226. return _this2.renderRow(child, index, {
  227. prefixCls: prefixCls
  228. }, bordered, layout, colon);
  229. })])])]
  230. )]
  231. );
  232. }
  233. };
  234. Descriptions.install = function (Vue) {
  235. Vue.use(Base);
  236. Vue.component(Descriptions.name, Descriptions);
  237. Vue.component(Descriptions.Item.name, Descriptions.Item);
  238. };
  239. export default Descriptions;