2024-08-09 10:57:46 +08:00
|
|
|
|
<script setup lang="ts">
|
2025-01-01 11:39:49 +08:00
|
|
|
|
import type { CSSProperties } from 'vue';
|
|
|
|
|
|
|
|
|
|
import { computed, ref, watchEffect } from 'vue';
|
2024-08-09 10:57:46 +08:00
|
|
|
|
|
|
|
|
|
import { VbenTooltip } from '@vben-core/shadcn-ui';
|
|
|
|
|
|
2025-02-12 14:25:12 +08:00
|
|
|
|
import { useElementSize } from '@vueuse/core';
|
|
|
|
|
|
2024-08-09 10:57:46 +08:00
|
|
|
|
interface Props {
|
|
|
|
|
/**
|
|
|
|
|
* 是否启用点击文本展开全部
|
|
|
|
|
* @default false
|
|
|
|
|
*/
|
|
|
|
|
expand?: boolean;
|
|
|
|
|
/**
|
|
|
|
|
* 文本最大行数
|
|
|
|
|
* @default 1
|
|
|
|
|
*/
|
|
|
|
|
line?: number;
|
|
|
|
|
/**
|
|
|
|
|
* 文本最大宽度
|
|
|
|
|
* @default '100%'
|
|
|
|
|
*/
|
|
|
|
|
maxWidth?: number | string;
|
|
|
|
|
/**
|
|
|
|
|
* 提示框位置
|
|
|
|
|
* @default 'top'
|
|
|
|
|
*/
|
2024-08-11 20:05:52 +08:00
|
|
|
|
placement?: 'bottom' | 'left' | 'right' | 'top';
|
2024-08-09 10:57:46 +08:00
|
|
|
|
/**
|
|
|
|
|
* 是否启用文本提示框
|
|
|
|
|
* @default true
|
|
|
|
|
*/
|
|
|
|
|
tooltip?: boolean;
|
|
|
|
|
/**
|
|
|
|
|
* 提示框背景颜色,优先级高于 overlayStyle
|
|
|
|
|
*/
|
|
|
|
|
tooltipBackgroundColor?: string;
|
|
|
|
|
/**
|
|
|
|
|
* 提示文本字体颜色,优先级高于 overlayStyle
|
|
|
|
|
*/
|
|
|
|
|
tooltipColor?: string;
|
|
|
|
|
/**
|
|
|
|
|
* 提示文本字体大小,单位px,优先级高于 overlayStyle
|
|
|
|
|
*/
|
|
|
|
|
tooltipFontSize?: number;
|
|
|
|
|
/**
|
|
|
|
|
* 提示框内容最大宽度,单位px,默认不设置时,提示文本内容自动与展示文本宽度保持一致
|
|
|
|
|
*/
|
|
|
|
|
tooltipMaxWidth?: number;
|
|
|
|
|
/**
|
|
|
|
|
* 提示框内容区域样式
|
|
|
|
|
* @default { textAlign: 'justify' }
|
|
|
|
|
*/
|
2024-08-11 20:05:52 +08:00
|
|
|
|
tooltipOverlayStyle?: CSSProperties;
|
2024-08-09 10:57:46 +08:00
|
|
|
|
}
|
2024-08-11 21:01:22 +08:00
|
|
|
|
|
2024-08-09 10:57:46 +08:00
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
|
|
|
expand: false,
|
|
|
|
|
line: 1,
|
|
|
|
|
maxWidth: '100%',
|
|
|
|
|
placement: 'top',
|
|
|
|
|
tooltip: true,
|
|
|
|
|
tooltipBackgroundColor: '',
|
|
|
|
|
tooltipColor: '',
|
|
|
|
|
tooltipFontSize: 14,
|
|
|
|
|
tooltipMaxWidth: undefined,
|
|
|
|
|
tooltipOverlayStyle: () => ({ textAlign: 'justify' }),
|
|
|
|
|
});
|
|
|
|
|
const emit = defineEmits<{ expandChange: [boolean] }>();
|
|
|
|
|
|
|
|
|
|
const textMaxWidth = computed(() => {
|
|
|
|
|
if (typeof props.maxWidth === 'number') {
|
|
|
|
|
return `${props.maxWidth}px`;
|
|
|
|
|
}
|
|
|
|
|
return props.maxWidth;
|
|
|
|
|
});
|
|
|
|
|
const ellipsis = ref();
|
2024-08-13 20:58:47 +08:00
|
|
|
|
const isExpand = ref(false);
|
2024-08-09 10:57:46 +08:00
|
|
|
|
const defaultTooltipMaxWidth = ref();
|
2024-08-13 20:58:47 +08:00
|
|
|
|
|
2025-02-12 14:25:12 +08:00
|
|
|
|
const { width: eleWidth } = useElementSize(ellipsis);
|
|
|
|
|
|
2024-08-09 10:57:46 +08:00
|
|
|
|
watchEffect(
|
|
|
|
|
() => {
|
2025-02-12 14:25:12 +08:00
|
|
|
|
if (props.tooltip && eleWidth.value) {
|
2024-08-09 10:57:46 +08:00
|
|
|
|
defaultTooltipMaxWidth.value =
|
2025-02-12 14:25:12 +08:00
|
|
|
|
props.tooltipMaxWidth ?? eleWidth.value + 24;
|
2024-08-09 10:57:46 +08:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{ flush: 'post' },
|
|
|
|
|
);
|
|
|
|
|
function onExpand() {
|
2024-08-13 20:58:47 +08:00
|
|
|
|
isExpand.value = !isExpand.value;
|
|
|
|
|
emit('expandChange', isExpand.value);
|
2024-08-09 10:57:46 +08:00
|
|
|
|
}
|
2024-08-11 20:05:52 +08:00
|
|
|
|
|
|
|
|
|
function handleExpand() {
|
2024-08-13 20:58:47 +08:00
|
|
|
|
props.expand && onExpand();
|
2024-08-11 20:05:52 +08:00
|
|
|
|
}
|
2024-08-09 10:57:46 +08:00
|
|
|
|
</script>
|
|
|
|
|
<template>
|
2024-08-25 23:40:52 +08:00
|
|
|
|
<div>
|
|
|
|
|
<VbenTooltip
|
|
|
|
|
:content-style="{
|
|
|
|
|
...tooltipOverlayStyle,
|
|
|
|
|
maxWidth: `${defaultTooltipMaxWidth}px`,
|
|
|
|
|
fontSize: `${tooltipFontSize}px`,
|
|
|
|
|
color: tooltipColor,
|
|
|
|
|
backgroundColor: tooltipBackgroundColor,
|
|
|
|
|
}"
|
|
|
|
|
:disabled="!props.tooltip || isExpand"
|
|
|
|
|
:side="placement"
|
|
|
|
|
>
|
|
|
|
|
<slot name="tooltip">
|
2024-08-09 10:57:46 +08:00
|
|
|
|
<slot></slot>
|
2024-08-25 23:40:52 +08:00
|
|
|
|
</slot>
|
|
|
|
|
|
|
|
|
|
<template #trigger>
|
|
|
|
|
<div
|
|
|
|
|
ref="ellipsis"
|
|
|
|
|
:class="{
|
|
|
|
|
'!cursor-pointer': expand,
|
2024-09-11 16:21:36 +08:00
|
|
|
|
['block truncate']: line === 1,
|
2024-08-25 23:40:52 +08:00
|
|
|
|
[$style.ellipsisMultiLine]: line > 1,
|
|
|
|
|
}"
|
|
|
|
|
:style="{
|
|
|
|
|
'-webkit-line-clamp': isExpand ? '' : line,
|
|
|
|
|
'max-width': textMaxWidth,
|
|
|
|
|
}"
|
|
|
|
|
class="cursor-text overflow-hidden"
|
|
|
|
|
@click="handleExpand"
|
|
|
|
|
v-bind="$attrs"
|
|
|
|
|
>
|
|
|
|
|
<slot></slot>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</VbenTooltip>
|
|
|
|
|
</div>
|
2024-08-09 10:57:46 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style module>
|
|
|
|
|
.ellipsisMultiLine {
|
|
|
|
|
display: -webkit-box;
|
|
|
|
|
-webkit-box-orient: vertical;
|
|
|
|
|
}
|
|
|
|
|
</style>
|