truncate-middle-text 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/dist/favicon.ico +0 -0
- package/dist/index.css +2 -0
- package/dist/index.js +52 -0
- package/dist/index.umd.cjs +1 -0
- package/dist/src/components/TruncateMiddleText/TruncateMiddleText.vue.d.ts +10 -0
- package/dist/src/components/TruncateMiddleText/index.d.ts +5 -0
- package/dist/src/components/TruncateMiddleText/truncateMiddleText.types.d.ts +11 -0
- package/dist/src/components/TruncateMiddleText/useIntersectionObserver.d.ts +13 -0
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/main.d.ts +1 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# 单行文本中间省略号
|
|
2
|
+
|
|
3
|
+
### 说明
|
|
4
|
+
针对单行文本中间省略号,特点:
|
|
5
|
+
1. 根据元素宽度自动触发单行文本中间省略号
|
|
6
|
+
2. 文字动态变更亦可以触发
|
|
7
|
+
3. 当隐藏元素(从超长文档中滚动到视图内)时,可以正确识别是否渲染中间省略号
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### 安装与使用
|
|
12
|
+
|
|
13
|
+
1. 安装
|
|
14
|
+
`pnpm i truncate-middle-text`
|
|
15
|
+
|
|
16
|
+
2. 在入口文件(通常是main.ts)引入全局样式
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import "truncate-middle-text/dist/index.css";
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. 固定列宽中使用
|
|
23
|
+
```vue
|
|
24
|
+
<template>
|
|
25
|
+
<div style="width: 150px;">
|
|
26
|
+
<TruncateMiddleText
|
|
27
|
+
:text="text"
|
|
28
|
+
:end-lenght="3"
|
|
29
|
+
link-color="red"
|
|
30
|
+
@truncate-click="handleTruncateClick"
|
|
31
|
+
/>
|
|
32
|
+
</div>
|
|
33
|
+
</template>
|
|
34
|
+
<script setup lang="ts">
|
|
35
|
+
import { TruncateMiddleText, type TruncateMiddleTextInstance } from "truncate-middle-text";
|
|
36
|
+
import { ref } from "vue";
|
|
37
|
+
|
|
38
|
+
const text = ref("问君能有几多愁,恰似一江春水向东流,问君能有几多愁,恰似一江春水向东流");
|
|
39
|
+
|
|
40
|
+
function handleTruncateClick(isLink: boolean) {
|
|
41
|
+
console.error(isLink);
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
### 注意事项
|
|
49
|
+
|
|
50
|
+
1)如果在左右布局的弹性布局中使用时需要注意在`TruncateMiddleText`组件外层包裹,并设置`overflow: hidden`才能做到动态中间省略号
|
|
51
|
+
|
|
52
|
+
```vue
|
|
53
|
+
<template>
|
|
54
|
+
<div style="display: flex; width: 200px;">
|
|
55
|
+
<span style="flex-shrink: 0;">左侧label</span>
|
|
56
|
+
<!-- 注意:这里需要设置 overflow: hidden 才能在弹性布局中自适应宽度 -->
|
|
57
|
+
<div style="overflow: hidden;">
|
|
58
|
+
<TruncateMiddleText
|
|
59
|
+
:text="text"
|
|
60
|
+
:end-lenght="3"
|
|
61
|
+
link-color="red"
|
|
62
|
+
@truncate-click="handleTruncateClick"
|
|
63
|
+
/>
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
</template>
|
|
67
|
+
<script setup lang="ts">
|
|
68
|
+
import { TruncateMiddleText, type TruncateMiddleTextInstance } from "truncate-middle-text";
|
|
69
|
+
import { ref } from "vue";
|
|
70
|
+
|
|
71
|
+
const text = ref("问君能有几多愁,恰似一江春水向东流,问君能有几多愁,恰似一江春水向东流");
|
|
72
|
+
|
|
73
|
+
function handleTruncateClick(isLink: boolean) {
|
|
74
|
+
console.error(isLink);
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### API
|
|
82
|
+
#### props
|
|
83
|
+
|
|
84
|
+
| 属性 | 类型 | 说明 |
|
|
85
|
+
| --------- | ------ | --------------------------------------------------------- |
|
|
86
|
+
| text | string | 渲染的文字 |
|
|
87
|
+
| endLenght | number | 文字尾部字符长度 |
|
|
88
|
+
| linkColor | string | 可选参数,链接字体和bottomBorder的颜色,默认为:*#4f90e1* |
|
|
89
|
+
|
|
90
|
+
### 事件
|
|
91
|
+
|
|
92
|
+
| 事件名称 | 类型 | 说明 |
|
|
93
|
+
| ------------- | ----------------------- | ------------------------------------------------------------ |
|
|
94
|
+
| truncateClick | (isLink: boolean): void | 点击TruncateMiddleText时的点击事件<br />isLink:当前文字是否被裁剪过,即是否出现中间省略号 |
|
|
95
|
+
|
package/dist/favicon.ico
ADDED
|
Binary file
|
package/dist/index.css
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { computed as e, createElementBlock as t, createElementVNode as n, defineComponent as r, normalizeStyle as i, onMounted as a, openBlock as o, ref as s, toDisplayString as c, toRef as l } from "vue";
|
|
2
|
+
//#region src/components/TruncateMiddleText/useIntersectionObserver.ts
|
|
3
|
+
function u({ prevRef: e, text: t }) {
|
|
4
|
+
let n = s(!1), r = new IntersectionObserver((t) => {
|
|
5
|
+
t.forEach((t) => {
|
|
6
|
+
t.isIntersecting && requestAnimationFrame(() => {
|
|
7
|
+
console.error("intersection observer"), (e.value?.scrollWidth || 0) > (e.value?.clientWidth || 0) ? n.value = !0 : n.value = !1;
|
|
8
|
+
});
|
|
9
|
+
});
|
|
10
|
+
}), i = new ResizeObserver(() => {
|
|
11
|
+
console.error("mutation oberser");
|
|
12
|
+
let t = e.value?.scrollWidth || 0, r = e.value?.clientWidth || 0;
|
|
13
|
+
console.error(t, r), t > r ? n.value = !0 : n.value = !1;
|
|
14
|
+
});
|
|
15
|
+
return a(() => {
|
|
16
|
+
e.value !== void 0 && (i.observe(e.value), r.observe(e.value));
|
|
17
|
+
}), { isLink: n };
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/components/TruncateMiddleText/TruncateMiddleText.vue?vue&type=script&setup=true&lang.ts
|
|
21
|
+
var d = { class: "truncate-middle-next" }, f = /* @__PURE__ */ r({
|
|
22
|
+
__name: "TruncateMiddleText",
|
|
23
|
+
props: {
|
|
24
|
+
text: {},
|
|
25
|
+
endLenght: {},
|
|
26
|
+
linkColor: { default: "#4f90e1" }
|
|
27
|
+
},
|
|
28
|
+
emits: ["truncateClick"],
|
|
29
|
+
setup(r, { emit: a }) {
|
|
30
|
+
let f = r, p = a, m = s(), { isLink: h } = u({
|
|
31
|
+
prevRef: m,
|
|
32
|
+
text: l(f, "text")
|
|
33
|
+
}), g = e(() => h.value ? {
|
|
34
|
+
borderBottom: `2px solid ${f.linkColor}`,
|
|
35
|
+
color: f.linkColor
|
|
36
|
+
} : {}), _ = e(() => f.text.length <= f.endLenght ? "" : f.text.slice(0, f.text.length - f.endLenght)), v = e(() => f.text.slice(-f.endLenght));
|
|
37
|
+
function y() {
|
|
38
|
+
p("truncateClick", h.value);
|
|
39
|
+
}
|
|
40
|
+
return (e, r) => (o(), t("div", {
|
|
41
|
+
class: "truncate-middle",
|
|
42
|
+
style: i(g.value),
|
|
43
|
+
onClick: y
|
|
44
|
+
}, [n("div", {
|
|
45
|
+
class: "truncate-middle-prev",
|
|
46
|
+
ref_key: "prevRef",
|
|
47
|
+
ref: m
|
|
48
|
+
}, c(_.value), 513), n("div", d, c(v.value), 1)], 4));
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
//#endregion
|
|
52
|
+
export { f as TruncateMiddleText, u as useIntersectionObserver };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("vue")):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e[`truancate-middle-text`]={},e.Vue))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function n({prevRef:e,text:n}){let r=(0,t.ref)(!1),i=new IntersectionObserver(t=>{t.forEach(t=>{t.isIntersecting&&requestAnimationFrame(()=>{console.error(`intersection observer`),(e.value?.scrollWidth||0)>(e.value?.clientWidth||0)?r.value=!0:r.value=!1})})}),a=new ResizeObserver(()=>{console.error(`mutation oberser`);let t=e.value?.scrollWidth||0,n=e.value?.clientWidth||0;console.error(t,n),t>n?r.value=!0:r.value=!1});return(0,t.onMounted)(()=>{e.value!==void 0&&(a.observe(e.value),i.observe(e.value))}),{isLink:r}}var r={class:`truncate-middle-next`};e.TruncateMiddleText=(0,t.defineComponent)({__name:`TruncateMiddleText`,props:{text:{},endLenght:{},linkColor:{default:`#4f90e1`}},emits:[`truncateClick`],setup(e,{emit:i}){let a=e,o=i,s=(0,t.ref)(),{isLink:c}=n({prevRef:s,text:(0,t.toRef)(a,`text`)}),l=(0,t.computed)(()=>c.value?{borderBottom:`2px solid ${a.linkColor}`,color:a.linkColor}:{}),u=(0,t.computed)(()=>a.text.length<=a.endLenght?``:a.text.slice(0,a.text.length-a.endLenght)),d=(0,t.computed)(()=>a.text.slice(-a.endLenght));function f(){o(`truncateClick`,c.value)}return(e,n)=>((0,t.openBlock)(),(0,t.createElementBlock)(`div`,{class:`truncate-middle`,style:(0,t.normalizeStyle)(l.value),onClick:f},[(0,t.createElementVNode)(`div`,{class:`truncate-middle-prev`,ref_key:`prevRef`,ref:s},(0,t.toDisplayString)(u.value),513),(0,t.createElementVNode)(`div`,r,(0,t.toDisplayString)(d.value),1)],4))}}),e.useIntersectionObserver=n});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { TruncateMiddleTextProps } from './truncateMiddleText.types';
|
|
2
|
+
declare const __VLS_export: import('vue').DefineComponent<TruncateMiddleTextProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
3
|
+
truncateClick: (isLink: boolean) => any;
|
|
4
|
+
}, string, import('vue').PublicProps, Readonly<TruncateMiddleTextProps> & Readonly<{
|
|
5
|
+
onTruncateClick?: ((isLink: boolean) => any) | undefined;
|
|
6
|
+
}>, {
|
|
7
|
+
linkColor: string;
|
|
8
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { default as TruncateMiddleText } from './TruncateMiddleText.vue';
|
|
2
|
+
export * from './truncateMiddleText.types';
|
|
3
|
+
export { default as TruncateMiddleText } from './TruncateMiddleText.vue';
|
|
4
|
+
export * from './useIntersectionObserver';
|
|
5
|
+
export type TruncateMiddleTextInstance = InstanceType<typeof TruncateMiddleText>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TruncateMiddleTextProps {
|
|
2
|
+
/** 要展示的文本 */
|
|
3
|
+
text: string;
|
|
4
|
+
/** 尾部字符疮毒 */
|
|
5
|
+
endLenght: number;
|
|
6
|
+
/** 链接的颜色,默认为 #4f90e1 */
|
|
7
|
+
linkColor?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface TruncateMiddleTextEmits {
|
|
10
|
+
(e: "truncateClick", isLink: boolean): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Ref } from 'vue';
|
|
2
|
+
export interface UseIntersectionObserverParams {
|
|
3
|
+
prevRef: Ref<HTMLSpanElement | undefined>;
|
|
4
|
+
text: Ref<string>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @description 通过 intersectionObserver 判断元素是否进入视口
|
|
8
|
+
* 如果 display: none 的容器切换为可见且视口内,会正确除法
|
|
9
|
+
* 但是某些边界情况(如 visibility: hidden) 行为不同
|
|
10
|
+
*/
|
|
11
|
+
export declare function useIntersectionObserver({ prevRef, text }: UseIntersectionObserverParams): {
|
|
12
|
+
isLink: Ref<boolean, boolean>;
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './TruncateMiddleText';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './components';
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "truncate-middle-text",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "./dist/index.umd.cjs",
|
|
5
|
+
"module": "./dist/index.js",
|
|
6
|
+
"types": "./dist/src/main.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"private": false,
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.umd.cjs",
|
|
16
|
+
"types": "./dist/src/main.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./dist/*": "./dist/*"
|
|
19
|
+
},
|
|
20
|
+
"keywords": ["truncate", "truncate middle", "中间省略号"],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "vite",
|
|
23
|
+
"build": "run-p type-check \"build-only {@}\" --",
|
|
24
|
+
"preview": "vite preview",
|
|
25
|
+
"build-only": "vite build",
|
|
26
|
+
"type-check": "vue-tsc --build",
|
|
27
|
+
"lint": "run-s lint:*",
|
|
28
|
+
"lint:oxlint": "oxlint . --fix",
|
|
29
|
+
"lint:eslint": "eslint . --fix --cache",
|
|
30
|
+
"format": "oxfmt src/"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"vue": "^3.5.32"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@tsconfig/node24": "^24.0.4",
|
|
37
|
+
"@types/node": "^24.12.2",
|
|
38
|
+
"@vitejs/plugin-vue": "^6.0.6",
|
|
39
|
+
"@vitejs/plugin-vue-jsx": "^5.1.5",
|
|
40
|
+
"@vue/eslint-config-typescript": "^14.7.0",
|
|
41
|
+
"@vue/tsconfig": "^0.9.1",
|
|
42
|
+
"eslint": "^10.2.1",
|
|
43
|
+
"eslint-config-prettier": "^10.1.8",
|
|
44
|
+
"eslint-plugin-oxlint": "~1.60.0",
|
|
45
|
+
"eslint-plugin-vue": "~10.8.0",
|
|
46
|
+
"jiti": "^2.6.1",
|
|
47
|
+
"npm-run-all2": "^8.0.4",
|
|
48
|
+
"oxfmt": "^0.45.0",
|
|
49
|
+
"oxlint": "~1.60.0",
|
|
50
|
+
"typescript": "~6.0.0",
|
|
51
|
+
"vite": "^8.0.8",
|
|
52
|
+
"vite-plugin-dts": "^5.0.1",
|
|
53
|
+
"vite-plugin-vue-devtools": "^8.1.1",
|
|
54
|
+
"vue-tsc": "^3.2.6"
|
|
55
|
+
},
|
|
56
|
+
"engines": {
|
|
57
|
+
"node": "^20.19.0 || >=22.12.0"
|
|
58
|
+
}
|
|
59
|
+
}
|