@vue-foldable/weibo
Version:
weibo foldable component for vue.js
315 lines (283 loc) • 8.66 kB
JavaScript
/*!
* @vue-foldable/weibo v1.0.0-alpha.1
* (c) 2016-preset ULIVZ
* Released under the MIT License.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.VueFoldableWeibo = {})));
}(this, (function (exports) { 'use strict';
var VueIcon = {
render: function render() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('svg', {
attrs: {
"xmlns": "http://www.w3.org/2000/svg",
"viewBox": "0 0 400 400",
"version": "1.1"
}
}, [_c('defs', {
attrs: {
"id": "defs6"
}
}), _vm._v(" "), _c('g', {
attrs: {
"transform": "matrix(1.3333333,0,0,-1.3333333,0,400)",
"id": "g10"
}
}, [_c('g', {
attrs: {
"transform": "translate(178.0626,235.0086)",
"id": "g12"
}
}, [_c('path', {
staticStyle: {
"fill": "#4dba87",
"fill-opacity": "1",
"fill-rule": "nonzero",
"stroke": "none"
},
attrs: {
"id": "path14",
"d": "M 0,0 -22.669,-39.264 -45.338,0 h -75.491 L -22.669,-170.017 75.491,0 Z"
}
})]), _vm._v(" "), _c('g', {
attrs: {
"transform": "translate(178.0626,235.0086)",
"id": "g16"
}
}, [_c('path', {
staticStyle: {
"fill": "#435466",
"fill-opacity": "1",
"fill-rule": "nonzero",
"stroke": "none"
},
attrs: {
"id": "path18",
"d": "M 0,0 -22.669,-39.264 -45.338,0 H -81.565 L -22.669,-102.01 36.227,0 Z"
}
})])])]);
},
staticRenderFns: []
};
var DEFAULT_VISUAL_HEIGHT = 100;
var VueFoldable = {
render: function render() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "vue-foldable"
}, [_c('div', {
ref: "container",
staticClass: "vue-foldable-container",
style: {
maxHeight: _vm.currentMaxHeight + 'px'
}
}, [_vm._t("default")], 2), _vm._v(" "), !_vm.noMask ? _c('div', {
staticClass: "vue-foldable-mask",
class: {
'collapsed': _vm.collapsed
}
}) : _vm._e(), _vm._v(" "), _vm._t("view-more", [_vm.reachThreshold ? _c('div', {
staticClass: "vue-foldable-view-more",
class: {
'collapsed': _vm.collapsed
},
on: {
"click": _vm.toggle
}
}, [_c('VueIcon', {
staticClass: "vue-foldable-icon",
class: {
'collapsed': _vm.collapsed
}
}), _vm._v(" "), _c('span', {
staticClass: "vue-foldable-text"
}, [_vm._v(" " + _vm._s(_vm.collapsed ? 'View more' : 'Collapse') + " ")])], 1) : _vm._e()], {
toggle: _vm.toggle,
collapsed: _vm.collapsed
})], 2);
},
staticRenderFns: [],
name: 'vue-foldable',
components: {
VueIcon: VueIcon
},
props: {
minHeight: {
type: Number,
default: DEFAULT_VISUAL_HEIGHT
},
height: {
type: [Number, String],
default: DEFAULT_VISUAL_HEIGHT
},
once: {
type: Boolean,
default: false
},
async: {
type: Boolean,
default: false
},
timeout: {
type: Number,
default: 3000
},
noMask: {
type: Boolean,
default: false
}
},
data: function data() {
var height = this.height;
if (typeof this.height === 'number' && this.height < this.minHeight) {
height = this.minHeight;
}
return {
collapsed: true,
currentMaxHeight: height,
threshold: height,
reachThreshold: true,
percentageMode: typeof this.height === 'string' && this.height.indexOf('%') !== -1,
percentage: null
};
},
created: function created() {
if (typeof this.height === 'string' && !this.percentageMode) {
this.currentMaxHeight = this.threshold = DEFAULT_VISUAL_HEIGHT;
}
if (this.percentageMode) {
this.percentage = parseInt(this.threshold.replace('%', '').trim()) / 100;
}
},
mounted: function mounted() {
this.handleMount(); // Temporary hack since this.$nextTick still cannot ensure all the sub components rendered.
// See: https://vuejs.org/v2/api/#mounted
setTimeout(this.handleMount, 50); // this.$nextTick(function () {
// this.handleMount()
// })
if (this.async) {
onElementHeightChange({
el: this.$refs.container,
callback: this.handleMount,
timeout: this.timeout
});
}
},
methods: {
handleMount: function handleMount() {
var contentHeight = this.$refs.container.scrollHeight;
this.calculateThreshold(contentHeight);
this.checkReachThresfold(contentHeight);
},
checkReachThresfold: function checkReachThresfold(contentHeight) {
this.reachThreshold = contentHeight > this.threshold;
},
calculateThreshold: function calculateThreshold(contentHeight) {
if (this.percentageMode) {
var calculatedHeight = contentHeight * this.percentage;
if (calculatedHeight < this.minHeight) {
calculatedHeight = this.minHeight;
}
this.currentMaxHeight = calculatedHeight;
this.threshold = calculatedHeight;
}
},
toggle: function toggle() {
this.collapsed = !this.collapsed;
if (this.collapsed) {
this.currentMaxHeight = this.threshold;
} else {
// explicitly set max height so that it can be transitioned
this.currentMaxHeight = this.$refs.container.scrollHeight;
if (this.once) {
this.reachThreshold = false;
}
}
}
}
};
function onElementHeightChange(_ref) {
var el = _ref.el,
callback = _ref.callback,
timeout = _ref.timeout;
var oldHeight = el.scrollHeight,
newHeight;
var poller;
var interval = 100;
var count = 0;
var maxCount = timeout / interval;
function unit() {
count++;
newHeight = el.scrollHeight;
if (oldHeight !== newHeight) {
callback(newHeight);
if (poller) {
clearTimeout(poller);
}
}
oldHeight = newHeight;
if (count <= maxCount) {
poller = setTimeout(unit, interval);
}
}
unit();
}
var weiboFoldable = {
render: function render() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('VueFoldable', {
staticClass: "weibo-foldable",
attrs: {
"height": "%50",
"async": ""
},
scopedSlots: _vm._u([{
key: "view-more",
fn: function fn(_ref) {
var toggle = _ref.toggle,
collapsed = _ref.collapsed;
return [_c('div', {
staticClass: "weibo-view-more",
class: {
'collapsed': collapsed
},
on: {
"click": toggle
}
}, [_vm._v(" " + _vm._s(collapsed ? '关注作者,查看全文' : '取消关注') + " "), _c('svg', {
staticClass: "icon-weibo-down",
attrs: {
"viewBox": "0 0 1048 1024",
"version": "1.1",
"xmlns": "http://www.w3.org/2000/svg"
}
}, [_c('path', {
attrs: {
"d": "M565.514 752.186c0.393-0.394 0.491-0.935 0.861-1.326l431.062-392.233c23.201-23.692 23.471-61.882 0.566-85.254-22.906-23.374-60.284-23.126-83.511 0.589l-390.168 355.025-390.933-355.739c-23.224-23.691-60.826-23.716-84.025-0.049-23.174 23.692-23.151 62.079 0.049 85.795l432.096 393.168c23.199 23.692 60.827 23.714 84.001 0.024z",
"fill": "#FF7D00"
}
})])])];
}
}])
}, [_vm._t("default")], 2);
},
staticRenderFns: [],
name: 'weibo-foldable',
components: {
VueFoldable: VueFoldable
}
};
exports.VueFoldable = VueFoldable;
exports.default = weiboFoldable;
Object.defineProperty(exports, '__esModule', { value: true });
})));
/* follow me on Twitter! @_ulivz */