Skip to content

Commit

Permalink
feat(components/text): remove left and right for ellipsis, add direct…
Browse files Browse the repository at this point in the history
…ion wrap and reverse to make text display correctly for ellipsis=start
  • Loading branch information
lejunyang committed Aug 30, 2024
1 parent aa0f05b commit 3af5e28
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 16 deletions.
38 changes: 23 additions & 15 deletions packages/components/src/components/text/Text.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,43 @@
import { defineSSRCustomElement } from 'custom';
import { createDefineElement, createImportStyle, processStringStyle } from 'utils';
import { createDefineElement, createImportStyle } from 'utils';
import { textEmits, textProps } from './type';
import { getCurrentInstance } from 'vue';
import { getCachedComputedStyle } from '@lun/utils';

const name = 'text';
const parts = [] as const;
const ellipsisStyle = `white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`;
const ellipsisStyle = `white-space:nowrap;overflow:hidden;text-overflow:ellipsis;`,
dirReverse: Record<string, string> = { ltr: 'rtl', rtl: 'ltr' };
export const Text = defineSSRCustomElement({
name,
props: textProps,
emits: textEmits,
setup(props) {
const { CE } = getCurrentInstance()!,
styleMap = getCachedComputedStyle(CE);
return () => {
const { text = '', ellipsisOffset, ellipsis } = props,
dir = styleMap.direction,
offset = +ellipsisOffset!;
if (offset && ellipsis) {
const style = (
<style>
{processStringStyle(`:host([ellipsis]){display:inline-flex}.ellipsis{${ellipsisStyle}flex:1}`, 0, true)}
</style>
);
if (ellipsis === 'end' || ellipsis === true)
return [style, <span class="ellipsis">{text.slice(0, -offset)}</span>, <span>{text.slice(-offset)}</span>];
if (ellipsis === 'start')
return [
style,
<span>{text.slice(0, offset)}</span>,
<span class="ellipsis" style={{ direction: 'rtl' }}>
{text.slice(offset)}
// 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>,
];
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 text;
};
},
Expand All @@ -42,9 +50,9 @@ 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([ellipsis]){display:inline-block;${ellipsisStyle}}` +
`:host([ellipsis=left]){direction:rtl}` +
`:host([ellipsis=right]){direction:ltr}` +
`:host(:where([ellipsis]:not([ellipsis=start]))){display:inline-block;${ellipsisStyle}}` +
`: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}}`,
Expand Down
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<'left' | 'middle' | 'right' | 'start' | 'end' | boolean>(),
ellipsis: PropBoolOrStr<'middle' | 'start' | 'end' | boolean>(),
// nice to have
maxLines: PropNumber(),
});
Expand Down

0 comments on commit 3af5e28

Please sign in to comment.