Skip to content

Commit e8ba5c2

Browse files
committed
✨ fix(text): enhance Text component with additional styling properties
- Added new props to the Text component: `lineClamp`, `lineHeight`, `noWrap`, `textDecoration`, `textTransform`, `whiteSpace`, and `wordBreak` for improved text styling flexibility. - Updated the documentation to reflect these new properties, enhancing clarity on their usage. - Modified the component's internal styling logic to accommodate the new props, ensuring they work seamlessly with existing features like ellipsis. This enhancement provides users with greater control over text presentation and layout. Signed-off-by: Innei <tukon479@gmail.com>
1 parent a40611f commit e8ba5c2

File tree

5 files changed

+102
-22
lines changed

5 files changed

+102
-22
lines changed

src/Text/Text.tsx

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,27 +22,49 @@ const Text: FC<TextProps> = ({
2222
underline,
2323
delete: deleteStyle,
2424
fontSize,
25+
lineClamp,
26+
lineHeight,
2527
mark,
2628
code,
2729
color,
2830
weight,
2931
ellipsis,
32+
noWrap,
33+
textDecoration,
34+
textTransform,
35+
whiteSpace,
36+
wordBreak,
3037
...rest
3138
}) => {
3239
const textRef = useRef<HTMLElement>(null);
3340
const isOverflow = useTextOverflow(textRef, ellipsis, children);
3441

42+
const isMultiEllipsis = typeof ellipsis === 'object' && !!ellipsis.rows && ellipsis.rows > 1;
3543
const tooltipWhenOverflow = typeof ellipsis === 'object' && ellipsis.tooltipWhenOverflow;
3644

3745
const textStyle = {
3846
...(color && { color }),
3947
...(weight && { fontWeight: weight }),
48+
...(lineHeight && { lineHeight }),
49+
...(textTransform && { textTransform }),
50+
...(textDecoration && { textDecoration }),
51+
...(wordBreak && { wordBreak }),
4052
...(typeof ellipsis === 'object' &&
4153
ellipsis.rows && {
4254
WebkitLineClamp: ellipsis.rows,
4355
}),
56+
...(!ellipsis &&
57+
!!lineClamp && {
58+
WebkitBoxOrient: 'vertical',
59+
WebkitLineClamp: lineClamp,
60+
display: '-webkit-box',
61+
overflow: 'hidden',
62+
textOverflow: 'ellipsis',
63+
}),
4464
...(fontSize && { fontSize }),
4565
...(align && { textAlign: align }),
66+
...(!isMultiEllipsis && noWrap && { whiteSpace: 'nowrap' as const }),
67+
...(whiteSpace && { whiteSpace }),
4668
...style,
4769
};
4870

@@ -78,14 +100,18 @@ const Text: FC<TextProps> = ({
78100
);
79101

80102
// 处理带有 tooltip 的省略
81-
if (ellipsis && typeof ellipsis === 'object' && ellipsis.tooltip) {
103+
if (
104+
ellipsis &&
105+
typeof ellipsis === 'object' &&
106+
(ellipsis.tooltip || ellipsis.tooltipWhenOverflow)
107+
) {
82108
// 如果设置了 tooltipWhenOverflow,只在溢出时显示 tooltip
83109
if (tooltipWhenOverflow && !isOverflow) {
84110
return content;
85111
}
86112

87113
const title = typeof ellipsis.tooltip === 'string' ? ellipsis.tooltip : children;
88-
if (typeof ellipsis.tooltip === 'object')
114+
if (ellipsis.tooltip && typeof ellipsis.tooltip === 'object')
89115
return (
90116
<Tooltip {...ellipsis.tooltip} title={ellipsis.tooltip?.title || title}>
91117
{content}

src/Text/demos/TooltipWhenOverflow.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import { Text } from '@lobehub/ui';
33
export default () => (
44
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
55
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
6-
<div>Container width: 200px (text overflows, tooltip shown)</div>
6+
<div>Container width: 200px (text overflows, tooltip shown; title defaults to children)</div>
77
<div style={{ width: 200 }}>
8-
<Text ellipsis={{ tooltip: true, tooltipWhenOverflow: true }}>
8+
<Text ellipsis={{ tooltipWhenOverflow: true }}>
99
This is a very long text that will overflow and show a tooltip when hovered.
1010
</Text>
1111
</div>
@@ -14,14 +14,14 @@ export default () => (
1414
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
1515
<div>Container width: 600px (text fits, no tooltip)</div>
1616
<div style={{ width: 600 }}>
17-
<Text ellipsis={{ tooltip: true, tooltipWhenOverflow: true }}>Short text that fits.</Text>
17+
<Text ellipsis={{ tooltipWhenOverflow: true }}>Short text that fits.</Text>
1818
</div>
1919
</div>
2020

2121
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
2222
<div>Multi-line ellipsis (2 rows, overflow detection)</div>
2323
<div style={{ width: 200 }}>
24-
<Text ellipsis={{ rows: 2, tooltip: true, tooltipWhenOverflow: true }}>
24+
<Text ellipsis={{ rows: 2, tooltipWhenOverflow: true }}>
2525
This is a very long text that spans multiple lines. It will be truncated after 2 rows and
2626
show a tooltip only when the content actually overflows.
2727
</Text>

src/Text/demos/index.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,31 @@ export default () => {
2424
value: 1,
2525
},
2626
italic: false,
27+
lineClamp: {
28+
max: 10,
29+
min: 1,
30+
step: 1,
31+
value: 0,
32+
},
33+
lineHeight: {
34+
value: '',
35+
},
2736
mark: false,
37+
noWrap: false,
2838
strong: false,
39+
textDecoration: {
40+
value: '',
41+
},
42+
textTransform: {
43+
options: ['', 'none', 'capitalize', 'uppercase', 'lowercase'],
44+
value: '',
45+
},
2946
tooltip: {
3047
render: (get) => get('ellipsis'),
3148
value: false,
3249
},
3350
tooltipWhenOverflow: {
34-
render: (get) => get('ellipsis') && get('tooltip'),
51+
render: (get) => get('ellipsis'),
3552
value: false,
3653
},
3754
type: {
@@ -43,6 +60,13 @@ export default () => {
4360
options: ['bold', 'bolder'],
4461
value: '',
4562
},
63+
whiteSpace: {
64+
value: '',
65+
},
66+
wordBreak: {
67+
options: ['', 'normal', 'break-all', 'keep-all', 'break-word'],
68+
value: '',
69+
},
4670
},
4771
{ store },
4872
) as any;
@@ -61,6 +85,12 @@ export default () => {
6185
}
6286
: undefined
6387
}
88+
lineClamp={controls.lineClamp ? controls.lineClamp : undefined}
89+
lineHeight={controls.lineHeight || undefined}
90+
textDecoration={controls.textDecoration || undefined}
91+
textTransform={controls.textTransform || undefined}
92+
whiteSpace={controls.whiteSpace || undefined}
93+
wordBreak={controls.wordBreak || undefined}
6494
>
6595
This is a very long text that will be truncated with ellipsis when it exceeds the
6696
container width. This is a very long text that will be truncated with ellipsis when it

src/Text/index.md

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,27 @@ description: Text component is used to display text content with various styles
1717

1818
### Text
1919

20-
| Property | Description | Type | Default |
21-
| --------- | ------------------------------ | ------------------------------------------------------------------- | ------- |
22-
| as | Custom element type | `ElementType` | `'div'` |
23-
| type | Text type | `'secondary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | - |
24-
| color | Custom text color | `string` | - |
25-
| weight | Font weight | `'bold' \| 'bolder' \| number` | - |
26-
| disabled | Whether the text is disabled | `boolean` | `false` |
27-
| strong | Whether the text is bold | `boolean` | `false` |
28-
| italic | Whether the text is italic | `boolean` | `false` |
29-
| underline | Whether the text is underlined | `boolean` | `false` |
30-
| delete | Whether the text is deleted | `boolean` | `false` |
31-
| mark | Whether the text is marked | `boolean` | `false` |
32-
| code | Whether the text is code | `boolean` | `false` |
33-
| ellipsis | Ellipsis configuration | `boolean \| { rows?: number; tooltip?: ReactNode \| TooltipProps }` | - |
20+
| Property | Description | Type | Default |
21+
| -------------- | ------------------------------- | ------------------------------------------------------------------- | ------- |
22+
| as | Custom element type | `ElementType` | `'div'` |
23+
| type | Text type | `'secondary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | - |
24+
| color | Custom text color | `string` | - |
25+
| weight | Font weight | `'bold' \| 'bolder' \| number` | - |
26+
| disabled | Whether the text is disabled | `boolean` | `false` |
27+
| strong | Whether the text is bold | `boolean` | `false` |
28+
| italic | Whether the text is italic | `boolean` | `false` |
29+
| lineClamp | Clamp lines with CSS line-clamp | `number` | - |
30+
| lineHeight | Custom line height | `CSSProperties['lineHeight']` | - |
31+
| underline | Whether the text is underlined | `boolean` | `false` |
32+
| delete | Whether the text is deleted | `boolean` | `false` |
33+
| mark | Whether the text is marked | `boolean` | `false` |
34+
| code | Whether the text is code | `boolean` | `false` |
35+
| noWrap | Whether to disable wrapping | `boolean` | `false` |
36+
| textDecoration | Custom text decoration | `CSSProperties['textDecoration']` | - |
37+
| textTransform | Custom text transform | `CSSProperties['textTransform']` | - |
38+
| whiteSpace | Custom white-space | `CSSProperties['whiteSpace']` | - |
39+
| wordBreak | Custom word-break | `CSSProperties['wordBreak']` | - |
40+
| ellipsis | Ellipsis configuration | `boolean \| { rows?: number; tooltip?: ReactNode \| TooltipProps }` | - |
3441

3542
Additionally, Text inherits all properties from Ant Design's Typography.Text component.
3643

src/Text/type.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ElementType, Ref } from 'react';
1+
import type { CSSProperties, ElementType, Ref } from 'react';
22

33
import type { TooltipProps } from '@/Tooltip';
44
import { DivProps } from '@/types';
@@ -19,10 +19,27 @@ export interface TextProps extends DivProps {
1919
};
2020
fontSize?: number | string;
2121
italic?: boolean;
22+
/**
23+
* Clamp lines with CSS line-clamp.
24+
*
25+
* Note: When `ellipsis` is provided, `ellipsis` takes precedence.
26+
*/
27+
lineClamp?: number;
28+
lineHeight?: CSSProperties['lineHeight'];
2229
mark?: boolean;
30+
/**
31+
* Whether to disable wrapping (set `white-space: nowrap`).
32+
*
33+
* Note: When multi-line ellipsis is enabled, it will be ignored.
34+
*/
35+
noWrap?: boolean;
2336
ref?: Ref<HTMLDivElement>;
2437
strong?: boolean;
38+
textDecoration?: CSSProperties['textDecoration'];
39+
textTransform?: CSSProperties['textTransform'];
2540
type?: 'secondary' | 'success' | 'warning' | 'danger' | 'info';
2641
underline?: boolean;
2742
weight?: 'bold' | 'bolder' | number;
43+
whiteSpace?: CSSProperties['whiteSpace'];
44+
wordBreak?: CSSProperties['wordBreak'];
2845
}

0 commit comments

Comments
 (0)