index.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. exports.__esModule = true;
  4. exports.default = void 0;
  5. var _utils = require("../utils");
  6. var _raf = require("../utils/dom/raf");
  7. var _bindEvent = require("../mixins/bind-event");
  8. var _icon = _interopRequireDefault(require("../icon"));
  9. var _createNamespace = (0, _utils.createNamespace)('notice-bar'),
  10. createComponent = _createNamespace[0],
  11. bem = _createNamespace[1];
  12. var _default = createComponent({
  13. mixins: [(0, _bindEvent.BindEventMixin)(function (bind) {
  14. // fix cache issues with forwards and back history in safari
  15. // see: https://guwii.com/cache-issues-with-forwards-and-back-history-in-safari/
  16. bind(window, 'pageshow', this.reset);
  17. })],
  18. inject: {
  19. vanPopup: {
  20. default: null
  21. }
  22. },
  23. props: {
  24. text: String,
  25. mode: String,
  26. color: String,
  27. leftIcon: String,
  28. wrapable: Boolean,
  29. background: String,
  30. scrollable: {
  31. type: Boolean,
  32. default: null
  33. },
  34. delay: {
  35. type: [Number, String],
  36. default: 1
  37. },
  38. speed: {
  39. type: [Number, String],
  40. default: 60
  41. }
  42. },
  43. data: function data() {
  44. return {
  45. show: true,
  46. offset: 0,
  47. duration: 0,
  48. wrapWidth: 0,
  49. contentWidth: 0
  50. };
  51. },
  52. watch: {
  53. scrollable: 'reset',
  54. text: {
  55. handler: 'reset',
  56. immediate: true
  57. }
  58. },
  59. created: function created() {
  60. // https://github.com/vant-ui/vant/issues/8634
  61. if (this.vanPopup) {
  62. this.vanPopup.onReopen(this.reset);
  63. }
  64. },
  65. activated: function activated() {
  66. this.reset();
  67. },
  68. methods: {
  69. onClickIcon: function onClickIcon(event) {
  70. if (this.mode === 'closeable') {
  71. this.show = false;
  72. this.$emit('close', event);
  73. }
  74. },
  75. onTransitionEnd: function onTransitionEnd() {
  76. var _this = this;
  77. this.offset = this.wrapWidth;
  78. this.duration = 0; // wait for Vue to render offset
  79. // using nextTick won't work in iOS14
  80. (0, _raf.raf)(function () {
  81. // use double raf to ensure animation can start
  82. (0, _raf.doubleRaf)(function () {
  83. _this.offset = -_this.contentWidth;
  84. _this.duration = (_this.contentWidth + _this.wrapWidth) / _this.speed;
  85. _this.$emit('replay');
  86. });
  87. });
  88. },
  89. // not an exposed-api, but may used by some users
  90. start: function start() {
  91. this.reset();
  92. },
  93. // @exposed-api
  94. reset: function reset() {
  95. var _this2 = this;
  96. var delay = (0, _utils.isDef)(this.delay) ? this.delay * 1000 : 0;
  97. this.offset = 0;
  98. this.duration = 0;
  99. this.wrapWidth = 0;
  100. this.contentWidth = 0;
  101. clearTimeout(this.startTimer);
  102. this.startTimer = setTimeout(function () {
  103. var _this2$$refs = _this2.$refs,
  104. wrap = _this2$$refs.wrap,
  105. content = _this2$$refs.content;
  106. if (!wrap || !content || _this2.scrollable === false) {
  107. return;
  108. }
  109. var wrapWidth = wrap.getBoundingClientRect().width;
  110. var contentWidth = content.getBoundingClientRect().width;
  111. if (_this2.scrollable || contentWidth > wrapWidth) {
  112. (0, _raf.doubleRaf)(function () {
  113. _this2.offset = -contentWidth;
  114. _this2.duration = contentWidth / _this2.speed;
  115. _this2.wrapWidth = wrapWidth;
  116. _this2.contentWidth = contentWidth;
  117. });
  118. }
  119. }, delay);
  120. }
  121. },
  122. render: function render() {
  123. var _this3 = this;
  124. var h = arguments[0];
  125. var slots = this.slots,
  126. mode = this.mode,
  127. leftIcon = this.leftIcon,
  128. onClickIcon = this.onClickIcon;
  129. var barStyle = {
  130. color: this.color,
  131. background: this.background
  132. };
  133. var contentStyle = {
  134. transform: this.offset ? "translateX(" + this.offset + "px)" : '',
  135. transitionDuration: this.duration + 's'
  136. };
  137. function LeftIcon() {
  138. var slot = slots('left-icon');
  139. if (slot) {
  140. return slot;
  141. }
  142. if (leftIcon) {
  143. return h(_icon.default, {
  144. "class": bem('left-icon'),
  145. "attrs": {
  146. "name": leftIcon
  147. }
  148. });
  149. }
  150. }
  151. function RightIcon() {
  152. var slot = slots('right-icon');
  153. if (slot) {
  154. return slot;
  155. }
  156. var iconName;
  157. if (mode === 'closeable') {
  158. iconName = 'cross';
  159. } else if (mode === 'link') {
  160. iconName = 'arrow';
  161. }
  162. if (iconName) {
  163. return h(_icon.default, {
  164. "class": bem('right-icon'),
  165. "attrs": {
  166. "name": iconName
  167. },
  168. "on": {
  169. "click": onClickIcon
  170. }
  171. });
  172. }
  173. }
  174. return h("div", {
  175. "attrs": {
  176. "role": "alert"
  177. },
  178. "directives": [{
  179. name: "show",
  180. value: this.show
  181. }],
  182. "class": bem({
  183. wrapable: this.wrapable
  184. }),
  185. "style": barStyle,
  186. "on": {
  187. "click": function click(event) {
  188. _this3.$emit('click', event);
  189. }
  190. }
  191. }, [LeftIcon(), h("div", {
  192. "ref": "wrap",
  193. "class": bem('wrap'),
  194. "attrs": {
  195. "role": "marquee"
  196. }
  197. }, [h("div", {
  198. "ref": "content",
  199. "class": [bem('content'), {
  200. 'van-ellipsis': this.scrollable === false && !this.wrapable
  201. }],
  202. "style": contentStyle,
  203. "on": {
  204. "transitionend": this.onTransitionEnd
  205. }
  206. }, [this.slots() || this.text])]), RightIcon()]);
  207. }
  208. });
  209. exports.default = _default;