-
+
@@ -12,6 +22,27 @@ export default {
type: String,
default: "",
},
+ modelValue: {
+ type: Boolean,
+ default: true,
+ },
+ },
+ emits: ["update:modelValue"],
+ data() {
+ return {
+ collapsed: this.modelValue,
+ };
+ },
+ watch: {
+ modelValue(val) {
+ this.collapsed = val;
+ },
+ },
+ methods: {
+ toggleCollapse() {
+ this.collapsed = !this.collapsed;
+ this.$emit("update:modelValue", this.collapsed);
+ },
},
};
@@ -21,13 +52,13 @@ export default {
width: 100%;
border: 1px solid var(--border-color, rgba(0, 0, 0, 0.1));
border-radius: 6px;
- padding: 8px;
position: relative;
margin-top: 8px;
+ transition: border 0.3s cubic-bezier(0.4, 0, 0.2, 1),
+ border-radius 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
-.border-label::before {
- content: attr(data-label);
+.label-header {
position: absolute;
top: -9px;
left: 16px;
@@ -37,6 +68,56 @@ export default {
line-height: 16px;
padding: 0 8px;
z-index: 1;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ cursor: pointer;
+ user-select: none;
+ margin-left: -12px;
+ transition: none;
+}
+
+.label-text {
+ transition: color 0.3s ease;
+}
+
+.collapse-icon {
+ opacity: 0.6;
+ transition: all 0.3s ease;
+ font-size: 18px;
+}
+
+.label-header:hover .label-text {
+ color: var(--q-primary);
+}
+
+.label-header:hover .collapse-icon {
+ opacity: 1;
+ color: var(--q-primary);
+}
+
+.content {
+ position: relative;
+ padding: 8px;
+ opacity: 1;
+ overflow: hidden;
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ margin: 0;
+}
+
+.content.collapsed {
+ padding-top: 0;
+ padding-bottom: 0;
+ height: 0;
+ opacity: 0;
+ margin: 0;
+}
+
+.border-label.collapsed {
+ border-width: 0;
+ border-top-width: 1px;
+ border-radius: 0;
+ margin: 8px 0;
}
.border-label::after {
@@ -49,12 +130,23 @@ export default {
background: inherit;
}
+/* 暗黑模式适配 */
.body--dark .border-label {
--border-color: rgba(255, 255, 255, 0.1);
}
-.body--dark .border-label::before {
+.body--dark .label-header {
background: #303133;
color: rgba(255, 255, 255, 0.7);
}
+
+/* 动画优化 */
+.border-label,
+.content {
+ will-change: max-height, padding, opacity, border-width;
+}
+
+.collapse-icon {
+ will-change: transform, opacity, color;
+}