@gitlab/ui
Version:
GitLab UI Components
160 lines (148 loc) • 3.97 kB
JavaScript
import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js';
//
var script = {
name: 'GlCollapse',
model: {
prop: 'visible',
event: 'input'
},
props: {
visible: {
type: Boolean,
default: false,
required: false
},
tag: {
type: String,
required: false,
default: 'div'
}
},
data() {
return {
show: this.visible,
transitioning: false
};
},
computed: {
classObject() {
const {
transitioning
} = this;
return {
collapse: !transitioning,
show: this.show && !transitioning
};
},
slotScope() {
return {
visible: this.show,
close: () => {
this.show = false;
}
};
},
transitionProps() {
return {
...this.$attrs,
css: true,
enterClass: '',
enterActiveClass: 'collapsing',
enterToClass: 'collapse show',
leaveClass: 'collapse show',
leaveActiveClass: 'collapsing',
leaveToClass: 'collapse'
};
}
},
watch: {
visible(newValue) {
if (newValue !== this.show) {
this.show = newValue;
}
},
show(newValue, oldValue) {
if (newValue !== oldValue) {
this.emitState();
}
}
},
mounted() {
this.$nextTick(() => {
this.emitState();
});
},
beforeDestroy() {
// Trigger state emit if needed
this.show = false;
},
methods: {
reflow(el) {
// Requesting an elements offsetHeight will trigger a reflow of the element content
// Without forcing a reflow, the browser optimize the operation and cause animation to fail
return Boolean(el && el.nodeType === Node.ELEMENT_NODE) && el.offsetHeight;
},
emitState() {
const {
show
} = this;
this.$emit('input', show);
},
enter(el) {
this.transitioning = true;
el.style.height = 0;
// In a `debounceByAnimationFrame()` for `appear` to work
window.requestAnimationFrame(() => {
this.reflow(el);
el.style.height = `${el.scrollHeight}px`;
});
},
afterEnter(el) {
this.transitioning = false;
this.$emit('shown');
el.style.height = '';
},
leave(el) {
this.transitioning = true;
el.style.height = 'auto';
el.style.display = 'block';
el.style.height = `${el.getBoundingClientRect().height}px`;
this.reflow(el);
el.style.height = 0;
},
afterLeave(el) {
this.transitioning = false;
this.$emit('hidden');
el.style.height = '';
}
}
};
/* script */
const __vue_script__ = script;
/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('transition',_vm._g(_vm._b({attrs:{"visible":_vm.visible},on:{"enter":_vm.enter,"after-enter":_vm.afterEnter,"leave":_vm.leave,"afterLeave":_vm.afterLeave}},'transition',_vm.transitionProps,false),_vm.$listeners),[_c(_vm.tag,{directives:[{name:"show",rawName:"v-show",value:(_vm.show),expression:"show"}],tag:"component",class:_vm.classObject},[_vm._t("default",null,null,_vm.slotScope)],2)],1)};
var __vue_staticRenderFns__ = [];
/* style */
const __vue_inject_styles__ = undefined;
/* scoped */
const __vue_scope_id__ = undefined;
/* module identifier */
const __vue_module_identifier__ = undefined;
/* functional template */
const __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__ = /*#__PURE__*/__vue_normalize__(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
export { __vue_component__ as default };