Steps.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import _extends from 'babel-runtime/helpers/extends';
  2. import _defineProperty from 'babel-runtime/helpers/defineProperty';
  3. import PropTypes from '../_util/vue-types';
  4. import BaseMixin from '../_util/BaseMixin';
  5. import debounce from 'lodash/debounce';
  6. import isFlexSupported from '../_util/isFlexSupported';
  7. import { filterEmpty, getEvents, getPropsData, getListeners } from '../_util/props-util';
  8. import { cloneElement } from '../_util/vnode';
  9. export default {
  10. name: 'Steps',
  11. mixins: [BaseMixin],
  12. props: {
  13. type: PropTypes.string.def('default'),
  14. prefixCls: PropTypes.string.def('rc-steps'),
  15. iconPrefix: PropTypes.string.def('rc'),
  16. direction: PropTypes.string.def('horizontal'),
  17. labelPlacement: PropTypes.string.def('horizontal'),
  18. status: PropTypes.string.def('process'),
  19. size: PropTypes.string.def(''),
  20. progressDot: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),
  21. initial: PropTypes.number.def(0),
  22. current: PropTypes.number.def(0),
  23. icons: PropTypes.shape({
  24. finish: PropTypes.any,
  25. error: PropTypes.any
  26. }).loose
  27. },
  28. data: function data() {
  29. this.calcStepOffsetWidth = debounce(this.calcStepOffsetWidth, 150);
  30. return {
  31. flexSupported: true,
  32. lastStepOffsetWidth: 0
  33. };
  34. },
  35. mounted: function mounted() {
  36. var _this = this;
  37. this.$nextTick(function () {
  38. _this.calcStepOffsetWidth();
  39. if (!isFlexSupported()) {
  40. _this.setState({
  41. flexSupported: false
  42. });
  43. }
  44. });
  45. },
  46. updated: function updated() {
  47. var _this2 = this;
  48. this.$nextTick(function () {
  49. _this2.calcStepOffsetWidth();
  50. });
  51. },
  52. beforeDestroy: function beforeDestroy() {
  53. if (this.calcTimeout) {
  54. clearTimeout(this.calcTimeout);
  55. }
  56. if (this.calcStepOffsetWidth && this.calcStepOffsetWidth.cancel) {
  57. this.calcStepOffsetWidth.cancel();
  58. }
  59. },
  60. methods: {
  61. onStepClick: function onStepClick(next) {
  62. var current = this.$props.current;
  63. if (current !== next) {
  64. this.$emit('change', next);
  65. }
  66. },
  67. calcStepOffsetWidth: function calcStepOffsetWidth() {
  68. var _this3 = this;
  69. if (isFlexSupported()) {
  70. return;
  71. }
  72. var lastStepOffsetWidth = this.$data.lastStepOffsetWidth;
  73. // Just for IE9
  74. var domNode = this.$refs.vcStepsRef;
  75. if (domNode.children.length > 0) {
  76. if (this.calcTimeout) {
  77. clearTimeout(this.calcTimeout);
  78. }
  79. this.calcTimeout = setTimeout(function () {
  80. // +1 for fit edge bug of digit width, like 35.4px
  81. var offsetWidth = (domNode.lastChild.offsetWidth || 0) + 1;
  82. // Reduce shake bug
  83. if (lastStepOffsetWidth === offsetWidth || Math.abs(lastStepOffsetWidth - offsetWidth) <= 3) {
  84. return;
  85. }
  86. _this3.setState({ lastStepOffsetWidth: offsetWidth });
  87. });
  88. }
  89. }
  90. },
  91. render: function render() {
  92. var _classString,
  93. _this4 = this;
  94. var h = arguments[0];
  95. var prefixCls = this.prefixCls,
  96. direction = this.direction,
  97. type = this.type,
  98. labelPlacement = this.labelPlacement,
  99. iconPrefix = this.iconPrefix,
  100. status = this.status,
  101. size = this.size,
  102. current = this.current,
  103. $scopedSlots = this.$scopedSlots,
  104. initial = this.initial,
  105. icons = this.icons;
  106. var isNav = type === 'navigation';
  107. var progressDot = this.progressDot;
  108. if (progressDot === undefined) {
  109. progressDot = $scopedSlots.progressDot;
  110. }
  111. var lastStepOffsetWidth = this.lastStepOffsetWidth,
  112. flexSupported = this.flexSupported;
  113. var filteredChildren = filterEmpty(this.$slots['default']);
  114. var lastIndex = filteredChildren.length - 1;
  115. var adjustedlabelPlacement = progressDot ? 'vertical' : labelPlacement;
  116. var classString = (_classString = {}, _defineProperty(_classString, prefixCls, true), _defineProperty(_classString, prefixCls + '-' + direction, true), _defineProperty(_classString, prefixCls + '-' + size, size), _defineProperty(_classString, prefixCls + '-label-' + adjustedlabelPlacement, direction === 'horizontal'), _defineProperty(_classString, prefixCls + '-dot', !!progressDot), _defineProperty(_classString, prefixCls + '-navigation', isNav), _defineProperty(_classString, prefixCls + '-flex-not-supported', !flexSupported), _classString);
  117. var listeners = getListeners(this);
  118. var stepsProps = {
  119. 'class': classString,
  120. ref: 'vcStepsRef',
  121. on: listeners
  122. };
  123. return h(
  124. 'div',
  125. stepsProps,
  126. [filteredChildren.map(function (child, index) {
  127. var childProps = getPropsData(child);
  128. var stepNumber = initial + index;
  129. var stepProps = {
  130. props: _extends({
  131. stepNumber: '' + (stepNumber + 1),
  132. stepIndex: stepNumber,
  133. prefixCls: prefixCls,
  134. iconPrefix: iconPrefix,
  135. progressDot: _this4.progressDot,
  136. icons: icons
  137. }, childProps),
  138. on: getEvents(child),
  139. scopedSlots: $scopedSlots
  140. };
  141. if (listeners.change) {
  142. stepProps.on.stepClick = _this4.onStepClick;
  143. }
  144. if (!flexSupported && direction !== 'vertical') {
  145. if (isNav) {
  146. stepProps.props.itemWidth = 100 / (lastIndex + 1) + '%';
  147. stepProps.props.adjustMarginRight = 0;
  148. } else if (index !== lastIndex) {
  149. stepProps.props.itemWidth = 100 / lastIndex + '%';
  150. stepProps.props.adjustMarginRight = -Math.round(lastStepOffsetWidth / lastIndex + 1) + 'px';
  151. }
  152. }
  153. // fix tail color
  154. if (status === 'error' && index === current - 1) {
  155. stepProps['class'] = prefixCls + '-next-error';
  156. }
  157. if (!childProps.status) {
  158. if (stepNumber === current) {
  159. stepProps.props.status = status;
  160. } else if (stepNumber < current) {
  161. stepProps.props.status = 'finish';
  162. } else {
  163. stepProps.props.status = 'wait';
  164. }
  165. }
  166. stepProps.props.active = stepNumber === current;
  167. return cloneElement(child, stepProps);
  168. })]
  169. );
  170. }
  171. };