bv-collapse.js
2.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Generic collapse transion helper component
//
// Note:
// Applies the classes `collapse`, `show` and `collapsing`
// during the enter/leave transition phases only
// Although it appears that Vue may be leaving the classes
// in-place after the transition completes
import { extend, mergeData } from '../../../vue'
import { NAME_COLLAPSE_HELPER } from '../../../constants/components'
import { PROP_TYPE_BOOLEAN } from '../../../constants/props'
import { getBCR, reflow, removeStyle, requestAF, setStyle } from '../../../utils/dom'
import { makeProp } from '../../../utils/props'
// --- Helper methods ---
// Transition event handler helpers
const onEnter = el => {
setStyle(el, 'height', 0)
// In a `requestAF()` for `appear` to work
requestAF(() => {
reflow(el)
setStyle(el, 'height', `${el.scrollHeight}px`)
})
}
const onAfterEnter = el => {
removeStyle(el, 'height')
}
const onLeave = el => {
setStyle(el, 'height', 'auto')
setStyle(el, 'display', 'block')
setStyle(el, 'height', `${getBCR(el).height}px`)
reflow(el)
setStyle(el, 'height', 0)
}
const onAfterLeave = el => {
removeStyle(el, 'height')
}
// --- Constants ---
// Default transition props
// `appear` will use the enter classes
const TRANSITION_PROPS = {
css: true,
enterClass: '',
enterActiveClass: 'collapsing',
enterToClass: 'collapse show',
leaveClass: 'collapse show',
leaveActiveClass: 'collapsing',
leaveToClass: 'collapse'
}
// Default transition handlers
// `appear` will use the enter handlers
const TRANSITION_HANDLERS = {
enter: onEnter,
afterEnter: onAfterEnter,
leave: onLeave,
afterLeave: onAfterLeave
}
// --- Main component ---
export const props = {
// // If `true` (and `visible` is `true` on mount), animate initially visible
appear: makeProp(PROP_TYPE_BOOLEAN, false)
}
// --- Main component ---
// @vue/component
export const BVCollapse = /*#__PURE__*/ extend({
name: NAME_COLLAPSE_HELPER,
functional: true,
props,
render(h, { props, data, children }) {
return h(
'transition',
// We merge in the `appear` prop last
mergeData(data, { props: TRANSITION_PROPS, on: TRANSITION_HANDLERS }, { props }),
// Note: `<transition>` supports a single root element only
children
)
}
})