1
-
<script lang="jsx" setup>
1
+
<script lang="jsx">
2
2
import { addClass, removeClass } from '../../utils/dom.utils';
3
-
import { onMounted, ref, watchEffect } from 'vue';
4
-
5
-
const props = defineProps({
6
-
tag: { type: String, default: 'div' },
7
-
modelValue: { type: Boolean, default: false },
8
-
transition: { type: Number, default: 350 },
9
-
});
10
-
const emit = defineEmits(['show', 'shown', 'hide', 'hidden']);
11
3
12
4
const COLLAPSE = 'collapse';
13
5
const IN = 'in';
14
6
const COLLAPSING = 'collapsing';
15
-
let timeoutId = 0;
16
-
const element = ref(null);
17
7
18
-
function toggle(show) {
19
-
clearTimeout(timeoutId);
20
-
const el = element.value;
21
-
if (!el) {
22
-
return;
23
-
}
24
-
if (show) {
25
-
emit('show');
26
-
removeClass(el, COLLAPSE);
27
-
el.style.height = 'auto';
28
-
const height = window.getComputedStyle(el).height;
29
-
el.style.height = null;
30
-
addClass(el, COLLAPSING);
31
-
el.offsetHeight; // force repaint
32
-
el.style.height = height;
33
-
timeoutId = setTimeout(() => {
34
-
removeClass(el, COLLAPSING);
35
-
addClass(el, COLLAPSE);
8
+
export default {
9
+
props: {
10
+
tag: {
11
+
type: String,
12
+
default: 'div',
13
+
},
14
+
modelValue: {
15
+
type: Boolean,
16
+
default: false,
17
+
},
18
+
transition: {
19
+
type: Number,
20
+
default: 350,
21
+
},
22
+
},
23
+
emits: ['show', 'shown', 'hide', 'hidden'],
24
+
data() {
25
+
return {
26
+
timeoutId: 0,
27
+
};
28
+
},
29
+
watch: {
30
+
modelValue(show) {
31
+
this.toggle(show);
32
+
},
33
+
},
34
+
mounted() {
35
+
const el = this.$el;
36
+
addClass(el, COLLAPSE);
37
+
if (this.modelValue) {
36
38
addClass(el, IN);
37
-
el.style.height = null;
38
-
timeoutId = 0;
39
-
emit('shown');
40
-
}, props.transition);
41
-
} else {
42
-
emit('hide');
43
-
el.style.height = window.getComputedStyle(el).height;
44
-
removeClass(el, IN);
45
-
removeClass(el, COLLAPSE);
46
-
el.offsetHeight;
47
-
el.style.height = null;
48
-
addClass(el, COLLAPSING);
49
-
timeoutId = setTimeout(() => {
50
-
addClass(el, COLLAPSE);
51
-
removeClass(el, COLLAPSING);
52
-
el.style.height = null;
53
-
timeoutId = 0;
54
-
emit('hidden');
55
-
}, props.transition);
56
-
}
57
-
}
58
-
59
-
watchEffect(() => {
60
-
toggle(props.modelValue);
61
-
});
62
-
63
-
onMounted(() => {
64
-
addClass(element.value, COLLAPSE);
65
-
if (props.modelValue) {
66
-
addClass(element.value, IN);
67
-
}
68
-
});
69
-
</script>
70
-
71
-
<script lang="jsx">
72
-
import { defineComponent } from 'vue';
73
-
74
-
export default defineComponent({
39
+
}
40
+
},
41
+
methods: {
42
+
toggle(show) {
43
+
clearTimeout(this.timeoutId);
44
+
const el = this.$el;
45
+
if (show) {
46
+
this.$emit('show');
47
+
removeClass(el, COLLAPSE);
48
+
el.style.height = 'auto';
49
+
const height = window.getComputedStyle(el).height;
50
+
el.style.height = null;
51
+
addClass(el, COLLAPSING);
52
+
el.offsetHeight; // force repaint
53
+
el.style.height = height;
54
+
this.timeoutId = setTimeout(() => {
55
+
removeClass(el, COLLAPSING);
56
+
addClass(el, COLLAPSE);
57
+
addClass(el, IN);
58
+
el.style.height = null;
59
+
this.timeoutId = 0;
60
+
this.$emit('shown');
61
+
}, this.transition);
62
+
} else {
63
+
this.$emit('hide');
64
+
el.style.height = window.getComputedStyle(el).height;
65
+
removeClass(el, IN);
66
+
removeClass(el, COLLAPSE);
67
+
el.offsetHeight;
68
+
el.style.height = null;
69
+
addClass(el, COLLAPSING);
70
+
this.timeoutId = setTimeout(() => {
71
+
addClass(el, COLLAPSE);
72
+
removeClass(el, COLLAPSING);
73
+
el.style.height = null;
74
+
this.timeoutId = 0;
75
+
this.$emit('hidden');
76
+
}, this.transition);
77
+
}
78
+
},
79
+
},
75
80
render() {
76
81
const Tag = this.tag;
77
-
return <Tag ref="element">{this.$slots.default?.()}</Tag>;
82
+
return <Tag>{this.$slots.default?.()}</Tag>;
78
83
},
79
-
});
84
+
};
80
85
</script>
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4