UNPKG

vue3-chat-scroll-next

Version:

Automatic, yet conditional, scroll-to-bottom directive for Vue.js 3.0

94 lines (81 loc) 2.94 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global['vue-chat-scroll'] = factory()); }(this, (function () { 'use strict'; /** * @name VueJS vChatScroll (vue-chat-scroll) * @description Monitors an element and scrolls to the bottom if a new child is added * @author Theodore Messinezis <theo@theomessin.com> * @file v-chat-scroll directive definition */ var scrollToBottom = function scrollToBottom(el, smooth) { if (typeof el.scroll === "function") { el.scroll({ top: el.scrollHeight, behavior: smooth ? 'smooth' : 'instant' }); } else { el.scrollTop = el.scrollHeight; } }; var mount = function mount(el, binding) { var scrolled = false; el.addEventListener('scroll', function (e) { scrolled = el.scrollTop + el.clientHeight + 1 < el.scrollHeight; if (scrolled && el.scrollTop === 0) { el.dispatchEvent(new Event("v-chat-scroll-top-reached")); } }); new MutationObserver(function (e) { var config = binding.value || {}; if (config.enabled === false) return; var pause = config.always === false && scrolled; var addedNodes = e[e.length - 1].addedNodes.length; var removedNodes = e[e.length - 1].removedNodes.length; if (config.scrollonremoved) { if (pause || addedNodes != 1 && removedNodes != 1) return; } else { if (pause || addedNodes != 1) return; } var smooth = config.smooth; var loadingRemoved = !addedNodes && removedNodes === 1; if (loadingRemoved && config.scrollonremoved && 'smoothonremoved' in config) { smooth = config.smoothonremoved; } scrollToBottom(el, smooth); }).observe(el, { childList: true, subtree: true }); }; var vChatScroll = { mounted: function mounted(el, binding) { mount(el, binding); }, // For backwards compat with Vue 2.x bind: function bind(el, binding) { mount(el, binding); }, // For backwards compat with Vue 2.x inserted: function inserted(el, binding) { var config = binding.value || {}; scrollToBottom(el, config.notSmoothOnInit ? false : config.smooth); } }; /** * @name VueJS vChatScroll (vue-chat-scroll) * @description Monitors an element and scrolls to the bottom if a new child is added * @author Theodore Messinezis <theo@theomessin.com> * @file vue-chat-scroll plugin definition */ var VueChatScroll = { install: function install(Vue, options) { Vue.directive('chat-scroll', vChatScroll); } }; if (typeof window !== 'undefined' && window.Vue && window.Vue.use) { window.Vue.use(VueChatScroll); } return VueChatScroll; })));