Skip to content

Commit

Permalink
feat(components/text): remove ellipsis=middle, support ellipsis=cente…
Browse files Browse the repository at this point in the history
…r, change implementation
  • Loading branch information
lejunyang committed Aug 30, 2024
1 parent 3af5e28 commit b5a0e3b
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 29 deletions.
63 changes: 42 additions & 21 deletions packages/components/src/components/text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { createDefineElement, createImportStyle } from 'utils';
import { textEmits, textProps } from './type';
import { getCurrentInstance } from 'vue';
import { getCachedComputedStyle } from '@lun/utils';
import { getCompParts } from 'common';

const name = 'text';
const parts = [] as const;
const ellipsisStyle = `white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,
const parts = ['ellipsis', 'inner', 'offset'] as const;
const compParts = getCompParts(name, parts);
const hidden = 'overflow:hidden;',
ellipsisStyle = hidden + `white-space:nowrap;text-overflow:ellipsis;`,
dirReverse: Record<string, string> = { ltr: 'rtl', rtl: 'ltr' };
export const Text = defineSSRCustomElement({
name,
Expand All @@ -19,25 +22,43 @@ export const Text = defineSSRCustomElement({
const { text = '', ellipsisOffset, ellipsis } = props,
dir = styleMap.direction,
offset = +ellipsisOffset!;
if (offset && ellipsis) {
if (ellipsis === 'start')
const getReverse = (text: string, cls?: any) => {
return (
<span class={['ellipsis', cls]} dir={dirReverse[dir]} part={compParts[0]}>
<span dir={dir} part={compParts[1]}>
{text}
</span>
</span>
);
};

if (ellipsis === 'start') {
if (offset)
return [
<span>{text.slice(0, offset)}</span>,
<span part={compParts[2]}>{text.slice(0, offset)}</span>,
// the outer span uses dir-reverse to make the ellipsis appear on the other side, and inner span uses same dir as CE to make text and symbols right
// if we just use one span, though the ellipsis appear on the other side, the end symbol may be missed
<span class="ellipsis" dir={dirReverse[dir]}>
<span dir={dir}>{text.slice(offset)}</span>
</span>,
getReverse(text.slice(offset)),
];
else if (ellipsis)
return [<span class="ellipsis">{text.slice(0, -offset)}</span>, <span>{text.slice(-offset)}</span>];
}
if (ellipsis === 'start')
return (
<span class="ellipsis" dir={dirReverse[dir]}>
<span dir={dir}>{text}</span>
</span>
);
return getReverse(text);
} else if (ellipsis === 'center')
return [
dir === 'ltr' ? (
getReverse(text, `float`)
) : (
<span class="ellipsis float" part={compParts[0]}>
{text}
</span>
),
text,
];
else if (ellipsis && offset)
return [
<span class="ellipsis" part={compParts[0]}>
{text.slice(0, -offset)}
</span>,
<span part={compParts[2]}>{text.slice(-offset)}</span>,
];
return text;
};
},
Expand All @@ -50,11 +71,11 @@ export const defineText = createDefineElement(name, Text, {}, parts, {
// as this is mandatory style for ellipsis, put it in component, not in theme
common: createImportStyle(
name,
`:host(:where([ellipsis]:not([ellipsis=start]))){display:inline-block;${ellipsisStyle}}` +
`:host([ellipsis]){display:inline-block}` +
`:host(:where([ellipsis]:not([ellipsis=start],[ellipsis=center]))){${ellipsisStyle}}` +
`:host([ellipsis=center]){height:1.5em;line-height:1.5;${hidden}}` +
`:host([ellipsis=start]),:host([ellipsis-offset]){display:inline-flex;min-width:0}` +
`.ellipsis{${ellipsisStyle}flex:1}` +
`:host([ellipsis=middle]){text-overflow:unset}` +
// how to have a opposite direction?
`:host([ellipsis=middle])::before{content:attr(text);float:right;direction:rtl;width:50%;background:inherit;position:relative;background:white;${ellipsisStyle}}`,
`.float{float:right;width:50%;}`,
),
});
2 changes: 1 addition & 1 deletion packages/components/src/components/text/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const textProps = freeze({
as: PropString<'code' | 'link'>(),
truncate: PropString(),
ellipsisOffset: PropNumber(),
ellipsis: PropBoolOrStr<'middle' | 'start' | 'end' | boolean>(),
ellipsis: PropBoolOrStr<'start' | 'end' | 'center' | boolean>(),
// nice to have
maxLines: PropNumber(),
});
Expand Down
13 changes: 9 additions & 4 deletions src/docs/components/text/ellipsis.vue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@ import { text, chText } from 'data';

export default () => (
<>
<l-text text={text} ellipsis="right"></l-text>
<l-text text={text} ellipsis="middle"></l-text>
<l-text text={chText} ellipsis="middle"></l-text>
<l-text text={text} ellipsis="left"></l-text>
end:
<l-text text={text} ellipsis></l-text>
<br />
center:
<l-text text={text} ellipsis="center" style="word-break: break-all"></l-text>
<l-text text={chText} ellipsis="center"></l-text>
<br />
start:
<l-text text={text} ellipsis="start"></l-text>
</>
);
9 changes: 9 additions & 0 deletions src/docs/components/text/ellipsisOffset.vue.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { text, chText } from 'data';

export default () => (
<>
<l-text text={text} ellipsis ellipsisOffset={5}></l-text>
<l-text text={chText} ellipsis ellipsisOffset={5}></l-text>
<l-text text={chText} ellipsis="start" ellipsisOffset={5}></l-text>
</>
);
14 changes: 12 additions & 2 deletions src/docs/components/text/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,20 @@ lang: zh-CN

## 单行超出隐藏

添加`ellipsis`属性即可使元素在限定宽度的容器中隐藏超出的内容,并显示省略号。省略号的位置默认为文档方向结束位置,可以设置`left`, `right`, `middle`来指定位置
添加`ellipsis`属性即可使元素在限定宽度的容器中隐藏超出的内容,并显示省略号。省略号的位置默认为文档方向结束(`end`)位置,可以设置`start``center`,其他所有值均视为`end`

:::warning 注
指定ellipsis位置是靠特定的direction(ltr和rtl)实现,这可能并不是一个很好的做法,谨慎使用,尤其是对于`ellipsis=middle`,其after伪元素使用了rtl,可以看到文本截断的位置不是很准确,而且段落最后的句号没有了,在rtl环境下还需要手动指定为ltr
谨慎使用`ellipsis=center`,其利用float实现,且依赖于元素的高度和行高一致。float左边可能会出现一些空白,需要手动调整右边的宽度以及设置`text-align``word-break`等等,比较不友好,而且在rtl下句尾的符号显示不正确。

若以后原生支持设置为[中间](https://github.com/w3c/csswg-drafts/issues/3937)则火速弃用现在的实现

推荐使用`ellipsisOffset`设置固定的偏移字符数来让省略号在中间显示,见下一小节
:::

<!-- @Code:ellipsis -->

## 省略号偏移

通过`ellipsisOffset`可设置省略号偏移的字符数,偏移的字符数以`ellipsis`的位置决定,例如当为`end`时偏移从`text`末尾算起,不支持`ellipsis=center`

<!-- @Code:ellipsisOffset -->
2 changes: 1 addition & 1 deletion src/utils/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const optionsGetter = async () => {

export const sentence = 'The quick brown fox jumps over the lazy dog.';
export const text = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo.`;
export const chText = `Lorem Ipsum,也称乱数假文或者哑元文本, 是印刷及排版领域所常用的虚拟文字。由于曾经一台匿名的打印机刻意打乱了一盒印刷字体从而造出一本字体样品书,Lorem Ipsum从西元15世纪起就被作为此领域的标准文本使用。它不仅延续了五个世纪,还通过了电子排版的挑战,其雏形却依然保存至今。`;
export const chText = `Lorem Ipsum,也称乱数假文或者哑元文本,是印刷及排版领域所常用的虚拟文字。由于曾经一台匿名的打印机刻意打乱了一盒印刷字体从而造出一本字体样品书,Lorem Ipsum从西元15世纪起就被作为此领域的标准文本使用。它不仅延续了五个世纪,还通过了电子排版的挑战,其雏形却依然保存至今。`;

export const growingProgress = ref(0);
setInterval(() => {
Expand Down

0 comments on commit b5a0e3b

Please sign in to comment.