Spin.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import { createVNode as _createVNode } from "vue";
  3. var __rest = this && this.__rest || function (s, e) {
  4. var t = {};
  5. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  6. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  7. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  8. }
  9. return t;
  10. };
  11. import { onBeforeUnmount, cloneVNode, isVNode, defineComponent, shallowRef, watch } from 'vue';
  12. import { debounce } from 'throttle-debounce';
  13. import PropTypes from '../_util/vue-types';
  14. import { filterEmpty, getPropsSlot } from '../_util/props-util';
  15. import initDefaultProps from '../_util/props-util/initDefaultProps';
  16. import useStyle from './style';
  17. import useConfigInject from '../config-provider/hooks/useConfigInject';
  18. export const spinProps = () => ({
  19. prefixCls: String,
  20. spinning: {
  21. type: Boolean,
  22. default: undefined
  23. },
  24. size: String,
  25. wrapperClassName: String,
  26. tip: PropTypes.any,
  27. delay: Number,
  28. indicator: PropTypes.any
  29. });
  30. // Render indicator
  31. let defaultIndicator = null;
  32. function shouldDelay(spinning, delay) {
  33. return !!spinning && !!delay && !isNaN(Number(delay));
  34. }
  35. export function setDefaultIndicator(Content) {
  36. const Indicator = Content.indicator;
  37. defaultIndicator = typeof Indicator === 'function' ? Indicator : () => _createVNode(Indicator, null, null);
  38. }
  39. export default defineComponent({
  40. compatConfig: {
  41. MODE: 3
  42. },
  43. name: 'ASpin',
  44. inheritAttrs: false,
  45. props: initDefaultProps(spinProps(), {
  46. size: 'default',
  47. spinning: true,
  48. wrapperClassName: ''
  49. }),
  50. setup(props, _ref) {
  51. let {
  52. attrs,
  53. slots
  54. } = _ref;
  55. const {
  56. prefixCls,
  57. size,
  58. direction
  59. } = useConfigInject('spin', props);
  60. const [wrapSSR, hashId] = useStyle(prefixCls);
  61. const sSpinning = shallowRef(props.spinning && !shouldDelay(props.spinning, props.delay));
  62. let updateSpinning;
  63. watch([() => props.spinning, () => props.delay], () => {
  64. updateSpinning === null || updateSpinning === void 0 ? void 0 : updateSpinning.cancel();
  65. updateSpinning = debounce(props.delay, () => {
  66. sSpinning.value = props.spinning;
  67. });
  68. updateSpinning === null || updateSpinning === void 0 ? void 0 : updateSpinning();
  69. }, {
  70. immediate: true,
  71. flush: 'post'
  72. });
  73. onBeforeUnmount(() => {
  74. updateSpinning === null || updateSpinning === void 0 ? void 0 : updateSpinning.cancel();
  75. });
  76. return () => {
  77. var _a, _b;
  78. const {
  79. class: cls
  80. } = attrs,
  81. divProps = __rest(attrs, ["class"]);
  82. const {
  83. tip = (_a = slots.tip) === null || _a === void 0 ? void 0 : _a.call(slots)
  84. } = props;
  85. const children = (_b = slots.default) === null || _b === void 0 ? void 0 : _b.call(slots);
  86. const spinClassName = {
  87. [hashId.value]: true,
  88. [prefixCls.value]: true,
  89. [`${prefixCls.value}-sm`]: size.value === 'small',
  90. [`${prefixCls.value}-lg`]: size.value === 'large',
  91. [`${prefixCls.value}-spinning`]: sSpinning.value,
  92. [`${prefixCls.value}-show-text`]: !!tip,
  93. [`${prefixCls.value}-rtl`]: direction.value === 'rtl',
  94. [cls]: !!cls
  95. };
  96. function renderIndicator(prefixCls) {
  97. const dotClassName = `${prefixCls}-dot`;
  98. let indicator = getPropsSlot(slots, props, 'indicator');
  99. // should not be render default indicator when indicator value is null
  100. if (indicator === null) {
  101. return null;
  102. }
  103. if (Array.isArray(indicator)) {
  104. indicator = indicator.length === 1 ? indicator[0] : indicator;
  105. }
  106. if (isVNode(indicator)) {
  107. return cloneVNode(indicator, {
  108. class: dotClassName
  109. });
  110. }
  111. if (defaultIndicator && isVNode(defaultIndicator())) {
  112. return cloneVNode(defaultIndicator(), {
  113. class: dotClassName
  114. });
  115. }
  116. return _createVNode("span", {
  117. "class": `${dotClassName} ${prefixCls}-dot-spin`
  118. }, [_createVNode("i", {
  119. "class": `${prefixCls}-dot-item`
  120. }, null), _createVNode("i", {
  121. "class": `${prefixCls}-dot-item`
  122. }, null), _createVNode("i", {
  123. "class": `${prefixCls}-dot-item`
  124. }, null), _createVNode("i", {
  125. "class": `${prefixCls}-dot-item`
  126. }, null)]);
  127. }
  128. const spinElement = _createVNode("div", _objectSpread(_objectSpread({}, divProps), {}, {
  129. "class": spinClassName,
  130. "aria-live": "polite",
  131. "aria-busy": sSpinning.value
  132. }), [renderIndicator(prefixCls.value), tip ? _createVNode("div", {
  133. "class": `${prefixCls.value}-text`
  134. }, [tip]) : null]);
  135. if (children && filterEmpty(children).length) {
  136. const containerClassName = {
  137. [`${prefixCls.value}-container`]: true,
  138. [`${prefixCls.value}-blur`]: sSpinning.value
  139. };
  140. return wrapSSR(_createVNode("div", {
  141. "class": [`${prefixCls.value}-nested-loading`, props.wrapperClassName, hashId.value]
  142. }, [sSpinning.value && _createVNode("div", {
  143. "key": "loading"
  144. }, [spinElement]), _createVNode("div", {
  145. "class": containerClassName,
  146. "key": "container"
  147. }, [children])]));
  148. }
  149. return wrapSSR(spinElement);
  150. };
  151. }
  152. });