main
vue 97 lines 1.86 KB
Raw
1 <template>
2 <div
3 class="collapse-box"
4 :style="arrowOffset ? `--arrow-offset: ${arrowOffset}` : undefined"
5 :class="[arrow ? `arrow arrow-${arrow}` : undefined, { show, embedded }]"
6 >
7 <div>
8 <slot />
9 </div>
10 </div>
11 </template>
12
13 <script setup lang="ts">
14 const { show, embedded, arrow, arrowOffset } = defineProps<{
15 show: boolean
16 embedded?: boolean
17 arrow?: "top-left" | "top-right" | "top"
18 arrowOffset?: string
19 }>()
20 </script>
21
22 <style lang="scss" scoped>
23 .collapse-box {
24 --transition-time: 0.3s;
25 --arrow-size: 10px;
26 --arrow-offset: 8px;
27 overflow: hidden;
28 display: grid;
29 grid-template-rows: 0fr;
30 padding-top: 0px;
31 opacity: 0;
32 position: relative;
33 transition:
34 opacity var(--transition-time) var(--bezier-ease),
35 grid-template-rows var(--transition-time) var(--bezier-ease),
36 padding-top var(--transition-time) var(--bezier-ease);
37
38 &.arrow-top,
39 &.arrow-top-left,
40 &.arrow-top-right {
41 &::after {
42 content: "";
43 width: 0;
44 height: 0;
45 border-left: var(--arrow-size) solid transparent;
46 border-right: var(--arrow-size) solid transparent;
47 border-bottom: var(--arrow-size) solid var(--bg-secondary-color);
48 position: absolute;
49 transition: transform var(--transition-time) var(--bezier-ease);
50
51 top: 2px;
52 transform: rotateX(90deg);
53 transform-origin: top center;
54 }
55 }
56 &.arrow-top {
57 &::after {
58 margin-left: calc(var(--arrow-size) / -2);
59 left: 50%;
60 }
61 }
62 &.arrow-top-left {
63 &::after {
64 left: var(--arrow-offset);
65 right: initial;
66 }
67 }
68 &.arrow-top-right {
69 &::after {
70 right: var(--arrow-offset);
71 left: initial;
72 }
73 }
74
75 & > * {
76 overflow: hidden;
77 }
78
79 &.embedded > * {
80 background-color: var(--bg-secondary-color);
81 border-radius: var(--border-radius);
82 }
83
84 &.show {
85 grid-template-rows: 1fr;
86 opacity: 1;
87
88 &.arrow {
89 padding-top: calc(var(--spacing) * 3);
90
91 &::after {
92 transform: rotateX(0deg);
93 }
94 }
95 }
96 }
97 </style>