Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ellipsis-text component #4019

Merged
merged 23 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b3780c1
chore: define components router
wangjue666 Aug 3, 2024
3c24632
chore: 组件路由放置到演示路由下
wangjue666 Aug 3, 2024
1309cf3
Revert "chore: 组件路由放置到演示路由下"
wangjue666 Aug 5, 2024
ffe11de
chore: typo
wangjue666 Aug 5, 2024
ff534a1
chore: 增加密码强度组件
wangjue666 Aug 5, 2024
24bd60e
chore: 国际化密码强度的菜单
wangjue666 Aug 5, 2024
4a11f2a
chore(@vben/web-antd): 迁移文本省略组件
wangjue666 Aug 6, 2024
0dab098
chore: typo
wangjue666 Aug 6, 2024
9b180cb
chore: 组件命名方式遵从packages
likui628 Aug 6, 2024
6bf7112
chore: Optimize the onExpand function
wangjue666 Aug 7, 2024
301b709
chore: update css
wangjue666 Aug 7, 2024
11b3460
chore(@vben/web-antd): optimize the getPosition function
wangjue666 Aug 7, 2024
362b169
chore: add ellipsis-text in comm-ui
wangjue666 Aug 7, 2024
b4cd5f2
chore: 文本省略组件迁移至common-ui
wangjue666 Aug 7, 2024
f7b310b
feat(@vben/common-ui): Tooltip的tip支持style传参
wangjue666 Aug 7, 2024
8d01a1f
chore: 优化组件渲染
wangjue666 Aug 7, 2024
127fa2c
chore: 使用css module解决样式冲突
wangjue666 Aug 7, 2024
0dbe66f
Merge branch 'main' into wangjue-define-comp-router
likui628 Aug 7, 2024
71d4c9e
chore: update props
wangjue666 Aug 8, 2024
d95de2b
Merge branch 'wangjue-define-comp-router' of https://github.com/vbenj…
wangjue666 Aug 8, 2024
5b84eae
Merge branch 'main' into wangjue-define-comp-router
wangjue666 Aug 8, 2024
5f6db64
chore: 优化css
wangjue666 Aug 8, 2024
6d80142
chore: rm unuse attr
wangjue666 Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion apps/web-antd/src/locales/langs/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@
"title": "Active Menu Icon",
"children": "Children Active Icon"
},
"fallback": { "title": "Fallback Page" },
"fallback": {
"title": "Fallback Page"
},
"features": {
"title": "Features",
"hideChildrenInMenu": "Hide Menu Children",
Expand All @@ -54,6 +56,12 @@
"level": "Level Mode",
"levelDetail": "Level Mode Detail"
}
},
"examples": {
"title": "Examples",
"ellipsis": {
"title": "EllipsisText"
}
}
}
}
6 changes: 6 additions & 0 deletions apps/web-antd/src/locales/langs/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
"levelDetail": "层级模式详情",
"lateralDetail": "平级模式详情"
}
},
"examples": {
"title": "示例",
"ellipsis": {
"title": "文本省略"
}
}
}
}
30 changes: 30 additions & 0 deletions apps/web-antd/src/router/routes/modules/examples.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import type { RouteRecordRaw } from 'vue-router';

import { BasicLayout } from '#/layouts';
import { $t } from '#/locales';

const routes: RouteRecordRaw[] = [
{
component: BasicLayout,
meta: {
icon: 'ion:layers-outline',
keepAlive: true,
order: 1000,
title: $t('page.examples.title'),
},
name: 'Examples',
path: '/examples',
children: [
{
name: 'EllipsisDemo',
path: '/examples/ellipsis',
component: () => import('#/views/examples/ellipsis/index.vue'),
meta: {
title: $t('page.examples.ellipsis.title'),
},
},
],
},
];

export default routes;
2 changes: 2 additions & 0 deletions apps/web-antd/src/views/examples/ellipsis/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const longText: string =
'Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。';
wangjue666 marked this conversation as resolved.
Show resolved Hide resolved
42 changes: 42 additions & 0 deletions apps/web-antd/src/views/examples/ellipsis/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script lang="ts" setup>
import { ref } from 'vue';

import { EllipsisText } from '@vben/common-ui';

import { Collapse, CollapsePanel } from 'ant-design-vue';

import { longText } from './data';

const text = ref(longText);
const activeKey = ref(['1', '2', '3', '4']);
</script>

<template>
<div class="card-box p-5">
<h1 class="mb-5 text-xl font-semibold">文本省略示例</h1>
<div>
<Collapse v-model:activeKey="activeKey">
<CollapsePanel key="1" header="Ellipsis 基本使用">
<EllipsisText :max-width="240">{{ text }}</EllipsisText>
</CollapsePanel>
<CollapsePanel key="2" header="Ellipsis 多行省略">
<EllipsisText :line="2">{{ text }}</EllipsisText>
</CollapsePanel>
<CollapsePanel key="3" header="Ellipsis 点击展开">
<EllipsisText :line="3" expand>{{ text }}</EllipsisText>
</CollapsePanel>
<CollapsePanel key="4" header="Ellipsis 定制 Tooltip 内容">
<EllipsisText :max-width="240">
住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪
<template #tooltip>
<div style="text-align: center">
《秦皇岛》<br />住在我心里孤独的<br />孤独的海怪 痛苦之王<br />开始厌倦
深海的光 停滞的海浪
</div>
</template>
</EllipsisText>
</CollapsePanel>
</Collapse>
</div>
</div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {

interface Props {
contentClass?: HTMLAttributes['class'];
contentStyle?: HTMLAttributes['style'];
delayDuration?: number;
side: TooltipContentProps['side'];
}
Expand All @@ -31,6 +32,7 @@ withDefaults(defineProps<Props>(), {
<TooltipContent
:class="contentClass"
:side="side"
:style="contentStyle"
class="side-content text-popover-foreground bg-popover"
>
<slot></slot>
Expand Down
145 changes: 145 additions & 0 deletions packages/effects/common-ui/src/ellipsis-text/ellipsis-text.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<script setup lang="ts">
import { computed, type CSSProperties, nextTick, ref, watchEffect } from 'vue';

import { VbenTooltip } from '@vben-core/shadcn-ui';

interface Props {
/**
* 是否启用点击文本展开全部
* @default false
*/
expand?: boolean;
/**
* 文本最大行数
* @default 1
*/
line?: number;
/**
* 文本最大宽度
* @default '100%'
*/
maxWidth?: number | string;
/**
* 提示框位置
* @default 'top'
*/
placement: 'bottom' | 'left' | 'right' | 'top';
/**
* 是否启用文本提示框
* @default true
*/
tooltip?: boolean;
/**
* 提示框背景颜色,优先级高于 overlayStyle
*/
tooltipBackgroundColor?: string;
/**
* 提示文本字体颜色,优先级高于 overlayStyle
*/
tooltipColor?: string;
/**
* 提示文本字体大小,单位px,优先级高于 overlayStyle
*/
tooltipFontSize?: number;
/**
* 提示框内容最大宽度,单位px,默认不设置时,提示文本内容自动与展示文本宽度保持一致
*/
tooltipMaxWidth?: number;
/**
* 提示框内容区域样式
* @default { textAlign: 'justify' }
*/
tooltipOverlayStyle?: CSSProperties; // 提示框内容区域样式
}
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 showTooltip = ref(false);
const ellipsis = ref();
const defaultTooltipMaxWidth = ref();
watchEffect(() => {
showTooltip.value = props.tooltip;
});
watchEffect(
() => {
if (props.tooltip && ellipsis.value) {
defaultTooltipMaxWidth.value =
props.tooltipMaxWidth ?? ellipsis.value.offsetWidth + 24;
}
},
{ flush: 'post' },
);
function onExpand() {
const { style } = ellipsis.value;
const isExpanded = !style['-webkit-line-clamp'];
if (props.tooltip) {
showTooltip.value = !isExpanded;
}

nextTick(() => {
style['-webkit-line-clamp'] = isExpanded ? props.line : '';
});

emit('expandChange', !isExpanded);
}
</script>
<template>
<VbenTooltip
:content-style="{
...tooltipOverlayStyle,
maxWidth: `${defaultTooltipMaxWidth}px`,
fontSize: `${tooltipFontSize}px`,
color: tooltipColor,
backgroundColor: tooltipBackgroundColor,
}"
:disabled="!showTooltip"
:overlay-style="tooltipOverlayStyle"
:side="placement"
>
<slot name="tooltip">
<slot></slot>
</slot>

<template #trigger>
<div
ref="ellipsis"
:class="{
'!cursor-pointer': expand,
['inline-block truncate']: line === 1,
[$style.ellipsisMultiLine]: line > 1,
}"
:style="`-webkit-line-clamp: ${line}; max-width: ${textMaxWidth};`"
class="cursor-text overflow-hidden"
@click="expand ? onExpand() : () => false"
v-bind="$attrs"
:data-line="line"
>
<slot></slot>
</div>
</template>
</VbenTooltip>
</template>

<style module>
.ellipsisMultiLine {
display: -webkit-box;
-webkit-box-orient: vertical;
}
</style>
1 change: 1 addition & 0 deletions packages/effects/common-ui/src/ellipsis-text/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as EllipsisText } from './ellipsis-text.vue';
1 change: 1 addition & 0 deletions packages/effects/common-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './about';
export * from './authentication';
export * from './dashboard';
export * from './ellipsis-text';
export * from './fallback';
export { useToast } from '@vben-core/shadcn-ui';
Loading