<template>
|
<section class="query-radio-bar-wrapper">
|
<div class="query-radio-bar-label">{{ label }}</div>
|
<div class="query-radio-bar-group-wrapper" ref="groupWrapperRef">
|
<el-radio-group
|
v-model="innerModelValue"
|
:class="{ collapsed }"
|
ref="groupRef"
|
:style="{ height: collapsed ? '20px' : `${groupHeight}px` }"
|
@change="(ev) => emit('change', ev)"
|
>
|
<slot></slot>
|
</el-radio-group>
|
</div>
|
<el-icon
|
v-if="showCollapseBtn"
|
:class="['query-radio-bar-icon', { uncollapse: !collapsed }]"
|
@click="handleCollapse"
|
>
|
<arrow-down />
|
</el-icon>
|
</section>
|
</template>
|
|
<script setup lang="ts">
|
import { useElementSize, useCssVar, useMutationObserver } from '@vueuse/core';
|
import _ from 'lodash';
|
// import { extractChildren } from '@/utils';
|
|
defineOptions({
|
name: 'QueryRadioBar',
|
});
|
|
type Props = {
|
label?: string;
|
modelValue?: string | number | boolean;
|
hasBtn?: boolean;
|
};
|
|
const props = withDefaults(defineProps<Props>(), {
|
hasBtn: true,
|
});
|
|
const emit = defineEmits<{
|
(e: 'update:modelValue', val: string | number | boolean): void;
|
(e: 'change', val: string | number | boolean): void;
|
}>();
|
|
const innerModelValue = computed({
|
get() {
|
return props.modelValue;
|
},
|
set(val) {
|
emit('update:modelValue', val);
|
},
|
});
|
|
const collapsed = ref(true);
|
|
function handleCollapse() {
|
collapsed.value = !collapsed.value;
|
}
|
|
const groupRef = ref();
|
const groupWrapperRef = ref();
|
// const collapseButtonWidth = ref(20);
|
|
const groupHeight = computed(() => {
|
if (!groupRef.value?.$el) {
|
return 0;
|
}
|
const $group = groupRef.value.$el;
|
return $group.scrollHeight;
|
});
|
|
const { width: groupWrapperWidth } = useElementSize(groupWrapperRef);
|
|
const margin = useCssVar('--bole-query-bar-group-item-margin');
|
|
const groupItemWidthList = ref<number[]>([]);
|
|
onMounted(() => {
|
setGroupItemWidthList();
|
});
|
|
useMutationObserver(
|
groupRef,
|
(mutations) => {
|
if (mutations.length) {
|
setGroupItemWidthList();
|
} else {
|
groupItemWidthList.value = [];
|
}
|
},
|
{
|
childList: true,
|
}
|
);
|
|
function setGroupItemWidthList() {
|
const $group = groupRef.value.$el;
|
let list = [];
|
let groupItems = [].slice.call($group.querySelectorAll('label'));
|
|
for (let index = 0; index < groupItems.length; index++) {
|
const element = groupItems[index];
|
list.push(element.getBoundingClientRect().width + parseInt(margin.value));
|
}
|
groupItemWidthList.value = list;
|
}
|
|
const showCollapseBtn = computed(() => _.sum(groupItemWidthList.value) > groupWrapperWidth.value);
|
</script>
|
|
<style lang="scss" scoped>
|
@use '@/style/common.scss' as *;
|
|
.query-radio-bar-wrapper {
|
display: flex;
|
align-items: flex-start;
|
padding-right: boleGetCssVar('proTable', 'filter-bar-horizontal-padding');
|
padding-bottom: 10px;
|
padding-left: boleGetCssVar('proTable', 'filter-bar-horizontal-padding');
|
background-color: #ffffff;
|
|
&:first-of-type {
|
margin-top: -10px;
|
}
|
|
.query-radio-bar-label {
|
padding-right: 12px;
|
font-size: 14px;
|
color: getCssVar('text-color', 'regular');
|
line-height: 20px;
|
}
|
|
:deep(.el-radio__input) {
|
display: none;
|
}
|
|
:deep(.el-radio__label) {
|
padding-left: 0;
|
}
|
|
:deep(.el-radio) {
|
margin-right: boleGetCssVar('query-bar', 'group-item-margin');
|
height: 20px;
|
}
|
|
.query-radio-bar-group-wrapper {
|
overflow: hidden;
|
min-width: 0;
|
flex: 1;
|
}
|
|
.el-radio-group {
|
align-items: flex-start;
|
overflow: hidden;
|
transition: height 0.3s cubic-bezier(0.075, 0.82, 0.165, 1);
|
|
&.collapsed {
|
overflow: hidden;
|
// height: 20px;
|
}
|
}
|
|
.query-radio-bar-icon {
|
font-size: 20px;
|
color: boleGetCssVar('color', 'primary');
|
cursor: pointer;
|
transition: all 0.3s;
|
|
&.uncollapse {
|
transform: rotate(180deg);
|
}
|
}
|
}
|
</style>
|