1
-
<script lang="jsx">
1
+
<script lang="jsx" setup>
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']);
3
11
4
12
const COLLAPSE = 'collapse';
5
13
const IN = 'in';
6
14
const COLLAPSING = 'collapsing';
15
+
let timeoutId = 0;
16
+
const element = ref(null);
7
17
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) {
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);
38
36
addClass(el, IN);
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
-
},
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({
80
75
render() {
81
76
const Tag = this.tag;
82
-
return <Tag>{this.$slots.default?.()}</Tag>;
77
+
return <Tag ref="element">{this.$slots.default?.()}</Tag>;
83
78
},
84
-
};
79
+
});
85
80
</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