Badge.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = exports.badgeProps = void 0;
  7. var _vue = require("vue");
  8. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  9. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  10. var _vueTypes = _interopRequireDefault(require("../_util/vue-types"));
  11. var _ScrollNumber = _interopRequireDefault(require("./ScrollNumber"));
  12. var _classNames = _interopRequireDefault(require("../_util/classNames"));
  13. var _propsUtil = require("../_util/props-util");
  14. var _vnode = require("../_util/vnode");
  15. var _transition = require("../_util/transition");
  16. var _Ribbon = _interopRequireDefault(require("./Ribbon"));
  17. var _useConfigInject = _interopRequireDefault(require("../config-provider/hooks/useConfigInject"));
  18. var _isNumeric = _interopRequireDefault(require("../_util/isNumeric"));
  19. var _style = _interopRequireDefault(require("./style"));
  20. var _colors = require("../_util/colors");
  21. const badgeProps = () => ({
  22. /** Number to show in badge */
  23. count: _vueTypes.default.any.def(null),
  24. showZero: {
  25. type: Boolean,
  26. default: undefined
  27. },
  28. /** Max count to show */
  29. overflowCount: {
  30. type: Number,
  31. default: 99
  32. },
  33. /** whether to show red dot without number */
  34. dot: {
  35. type: Boolean,
  36. default: undefined
  37. },
  38. prefixCls: String,
  39. scrollNumberPrefixCls: String,
  40. status: {
  41. type: String
  42. },
  43. size: {
  44. type: String,
  45. default: 'default'
  46. },
  47. color: String,
  48. text: _vueTypes.default.any,
  49. offset: Array,
  50. numberStyle: {
  51. type: Object,
  52. default: undefined
  53. },
  54. title: String
  55. });
  56. exports.badgeProps = badgeProps;
  57. var _default = exports.default = (0, _vue.defineComponent)({
  58. compatConfig: {
  59. MODE: 3
  60. },
  61. name: 'ABadge',
  62. Ribbon: _Ribbon.default,
  63. inheritAttrs: false,
  64. props: badgeProps(),
  65. slots: Object,
  66. setup(props, _ref) {
  67. let {
  68. slots,
  69. attrs
  70. } = _ref;
  71. const {
  72. prefixCls,
  73. direction
  74. } = (0, _useConfigInject.default)('badge', props);
  75. const [wrapSSR, hashId] = (0, _style.default)(prefixCls);
  76. // ================================ Misc ================================
  77. const numberedDisplayCount = (0, _vue.computed)(() => {
  78. return props.count > props.overflowCount ? `${props.overflowCount}+` : props.count;
  79. });
  80. const isZero = (0, _vue.computed)(() => numberedDisplayCount.value === '0' || numberedDisplayCount.value === 0);
  81. const ignoreCount = (0, _vue.computed)(() => props.count === null || isZero.value && !props.showZero);
  82. const hasStatus = (0, _vue.computed)(() => (props.status !== null && props.status !== undefined || props.color !== null && props.color !== undefined) && ignoreCount.value);
  83. const showAsDot = (0, _vue.computed)(() => props.dot && !isZero.value);
  84. const mergedCount = (0, _vue.computed)(() => showAsDot.value ? '' : numberedDisplayCount.value);
  85. const isHidden = (0, _vue.computed)(() => {
  86. const isEmpty = mergedCount.value === null || mergedCount.value === undefined || mergedCount.value === '';
  87. return (isEmpty || isZero.value && !props.showZero) && !showAsDot.value;
  88. });
  89. // Count should be cache in case hidden change it
  90. const livingCount = (0, _vue.ref)(props.count);
  91. // We need cache count since remove motion should not change count display
  92. const displayCount = (0, _vue.ref)(mergedCount.value);
  93. // We will cache the dot status to avoid shaking on leaved motion
  94. const isDotRef = (0, _vue.ref)(showAsDot.value);
  95. (0, _vue.watch)([() => props.count, mergedCount, showAsDot], () => {
  96. if (!isHidden.value) {
  97. livingCount.value = props.count;
  98. displayCount.value = mergedCount.value;
  99. isDotRef.value = showAsDot.value;
  100. }
  101. }, {
  102. immediate: true
  103. });
  104. // InternalColor
  105. const isInternalColor = (0, _vue.computed)(() => (0, _colors.isPresetColor)(props.color, false));
  106. // Shared styles
  107. const statusCls = (0, _vue.computed)(() => ({
  108. [`${prefixCls.value}-status-dot`]: hasStatus.value,
  109. [`${prefixCls.value}-status-${props.status}`]: !!props.status,
  110. [`${prefixCls.value}-color-${props.color}`]: isInternalColor.value
  111. }));
  112. const statusStyle = (0, _vue.computed)(() => {
  113. if (props.color && !isInternalColor.value) {
  114. return {
  115. background: props.color,
  116. color: props.color
  117. };
  118. } else {
  119. return {};
  120. }
  121. });
  122. const scrollNumberCls = (0, _vue.computed)(() => ({
  123. [`${prefixCls.value}-dot`]: isDotRef.value,
  124. [`${prefixCls.value}-count`]: !isDotRef.value,
  125. [`${prefixCls.value}-count-sm`]: props.size === 'small',
  126. [`${prefixCls.value}-multiple-words`]: !isDotRef.value && displayCount.value && displayCount.value.toString().length > 1,
  127. [`${prefixCls.value}-status-${props.status}`]: !!props.status,
  128. [`${prefixCls.value}-color-${props.color}`]: isInternalColor.value
  129. }));
  130. return () => {
  131. var _a, _b;
  132. const {
  133. offset,
  134. title,
  135. color
  136. } = props;
  137. const style = attrs.style;
  138. const text = (0, _propsUtil.getPropsSlot)(slots, props, 'text');
  139. const pre = prefixCls.value;
  140. const count = livingCount.value;
  141. let children = (0, _propsUtil.flattenChildren)((_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots));
  142. children = children.length ? children : null;
  143. const visible = !!(!isHidden.value || slots.count);
  144. // =============================== Styles ===============================
  145. const mergedStyle = (() => {
  146. if (!offset) {
  147. return (0, _extends2.default)({}, style);
  148. }
  149. const offsetStyle = {
  150. marginTop: (0, _isNumeric.default)(offset[1]) ? `${offset[1]}px` : offset[1]
  151. };
  152. if (direction.value === 'rtl') {
  153. offsetStyle.left = `${parseInt(offset[0], 10)}px`;
  154. } else {
  155. offsetStyle.right = `${-parseInt(offset[0], 10)}px`;
  156. }
  157. return (0, _extends2.default)((0, _extends2.default)({}, offsetStyle), style);
  158. })();
  159. // =============================== Render ===============================
  160. // >>> Title
  161. const titleNode = title !== null && title !== void 0 ? title : typeof count === 'string' || typeof count === 'number' ? count : undefined;
  162. // >>> Status Text
  163. const statusTextNode = visible || !text ? null : (0, _vue.createVNode)("span", {
  164. "class": `${pre}-status-text`
  165. }, [text]);
  166. // >>> Display Component
  167. const displayNode = typeof count === 'object' || count === undefined && slots.count ? (0, _vnode.cloneElement)(count !== null && count !== void 0 ? count : (_b = slots.count) === null || _b === void 0 ? void 0 : _b.call(slots), {
  168. style: mergedStyle
  169. }, false) : null;
  170. const badgeClassName = (0, _classNames.default)(pre, {
  171. [`${pre}-status`]: hasStatus.value,
  172. [`${pre}-not-a-wrapper`]: !children,
  173. [`${pre}-rtl`]: direction.value === 'rtl'
  174. }, attrs.class, hashId.value);
  175. // <Badge status="success" />
  176. if (!children && hasStatus.value) {
  177. const statusTextColor = mergedStyle.color;
  178. return wrapSSR((0, _vue.createVNode)("span", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, attrs), {}, {
  179. "class": badgeClassName,
  180. "style": mergedStyle
  181. }), [(0, _vue.createVNode)("span", {
  182. "class": statusCls.value,
  183. "style": statusStyle.value
  184. }, null), (0, _vue.createVNode)("span", {
  185. "style": {
  186. color: statusTextColor
  187. },
  188. "class": `${pre}-status-text`
  189. }, [text])]));
  190. }
  191. const transitionProps = (0, _transition.getTransitionProps)(children ? `${pre}-zoom` : '', {
  192. appear: false
  193. });
  194. let scrollNumberStyle = (0, _extends2.default)((0, _extends2.default)({}, mergedStyle), props.numberStyle);
  195. if (color && !isInternalColor.value) {
  196. scrollNumberStyle = scrollNumberStyle || {};
  197. scrollNumberStyle.background = color;
  198. }
  199. return wrapSSR((0, _vue.createVNode)("span", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, attrs), {}, {
  200. "class": badgeClassName
  201. }), [children, (0, _vue.createVNode)(_transition.Transition, transitionProps, {
  202. default: () => [(0, _vue.withDirectives)((0, _vue.createVNode)(_ScrollNumber.default, {
  203. "prefixCls": props.scrollNumberPrefixCls,
  204. "show": visible,
  205. "class": scrollNumberCls.value,
  206. "count": displayCount.value,
  207. "title": titleNode,
  208. "style": scrollNumberStyle,
  209. "key": "scrollNumber"
  210. }, {
  211. default: () => [displayNode]
  212. }), [[_vue.vShow, visible]])]
  213. }), statusTextNode]));
  214. };
  215. }
  216. });