song-ui-u
Version:
vue3 + js的PC前端组件库
109 lines (106 loc) • 3.23 kB
JavaScript
import { defineComponent, inject, ref, provide, computed, onMounted, nextTick, createVNode } from 'vue';
import { COLLAPSE_KEY, COLLAPSE_ITEM_KEY } from '../constants.mjs';
import { useNamespace } from '../../../hook/use-namespace/index.mjs';
import 'song-ui-pro-icon';
import '../../../hook/use-zindex/index.mjs';
var collapseItem = /* @__PURE__ */ defineComponent({
name: "x-collapse-item",
props: {
name: {
type: String,
required: true
},
title: {
type: String,
default: ""
},
disabled: {
type: Boolean,
default: false
},
icon: {
type: String,
default: ""
}
},
setup(props, {
slots
}) {
const collapseCtx = inject(COLLAPSE_KEY);
const contentHeight = ref("0px");
const contentRef = ref(null);
const isTransitioning = ref(false);
provide(COLLAPSE_ITEM_KEY, {
props
});
const ns = useNamespace("collapse-item");
const isActive = computed(() => {
return collapseCtx?.isItemActive(props.name);
});
const handleHeaderClick = () => {
if (props.disabled) return;
collapseCtx?.handleItemClick(props.name);
};
const setContentHeight = async () => {
if (!contentRef.value) return;
isTransitioning.value = true;
if (isActive.value) {
contentHeight.value = "auto";
await nextTick();
const height = contentRef.value.offsetHeight;
contentHeight.value = "0px";
await new Promise((resolve) => requestAnimationFrame(resolve));
contentHeight.value = `${height}px`;
} else {
const height = contentRef.value.offsetHeight;
contentHeight.value = `${height}px`;
await new Promise((resolve) => requestAnimationFrame(resolve));
contentHeight.value = "0px";
}
setTimeout(() => {
isTransitioning.value = false;
if (isActive.value) {
contentHeight.value = "auto";
}
}, 300);
};
const watchActiveChange = computed(() => {
setContentHeight();
return isActive.value;
});
onMounted(() => {
collapseCtx?.setCollapseItems({
name: props.name,
title: props.title
});
if (isActive.value) {
nextTick(() => {
contentHeight.value = "auto";
});
}
});
return () => {
watchActiveChange.value;
return createVNode("div", {
"class": [ns.b(), isActive.value ? ns.is("active") : ""]
}, [createVNode("div", {
"class": [ns.e("title"), isActive.value ? ns.is("active") : "", props.disabled ? ns.is("disabled") : ""],
"onClick": handleHeaderClick
}, [props.icon && createVNode("i", {
"class": props.icon
}, null), props.title || slots.title?.(), createVNode("i", {
"class": [ns.e("title-arrow"), "x-icon-arrow-right"]
}, null)]), createVNode("div", {
"class": ns.e("content"),
"style": {
height: contentHeight.value
},
"ref": contentRef
}, [createVNode("div", {
"class": ns.e("content-box")
}, [slots.default?.()])])]);
};
}
});
export { collapseItem as default };
//# sourceMappingURL=collapse-item.mjs.map