Skip to content

Commit 9e90ad5

Browse files
committed
feat(Truncate): add true calculated middle truncate
1 parent b1cf0d2 commit 9e90ad5

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

packages/react-core/src/components/Truncate/Truncate.tsx

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ interface TruncateProps extends React.HTMLProps<HTMLSpanElement> {
2222
className?: string;
2323
/** Text to truncate */
2424
content: string;
25-
/** The number of characters displayed in the second half of the truncation */
25+
/** The number of characters displayed in the second half of the truncation. When using middle truncation, set this to 0 for true middle truncation.
26+
*/
2627
trailingNumChars?: number;
2728
/** Where the text will be truncated */
2829
position?: 'start' | 'middle' | 'end';
@@ -44,7 +45,15 @@ interface TruncateProps extends React.HTMLProps<HTMLSpanElement> {
4445
| 'right-end';
4546
}
4647

47-
const sliceContent = (str: string, slice: number) => [str.slice(0, str.length - slice), str.slice(-slice)];
48+
const sliceContent = (content: string, trailingChars: number) => {
49+
if (trailingChars === 0) {
50+
const middle = Math.floor(content.length / 2);
51+
const left = content.slice(0, middle);
52+
const right = content.slice(middle);
53+
return [left, right];
54+
}
55+
return [content.slice(0, content.length - trailingChars), content.slice(-trailingChars)];
56+
};
4857

4958
export const Truncate: React.FunctionComponent<TruncateProps> = ({
5059
className,
@@ -116,21 +125,34 @@ export const Truncate: React.FunctionComponent<TruncateProps> = ({
116125
{position === TruncatePosition.start && <React.Fragment>&lrm;</React.Fragment>}
117126
</span>
118127
)}
119-
{position === TruncatePosition.middle && content.length - trailingNumChars > minWidthCharacters && (
120-
<React.Fragment>
121-
<span ref={textRef} className={styles.truncateStart}>
122-
{sliceContent(content, trailingNumChars)[0]}
123-
</span>
124-
<span className={styles.truncateEnd}>{sliceContent(content, trailingNumChars)[1]}</span>
125-
</React.Fragment>
126-
)}
127-
{position === TruncatePosition.middle && content.length - trailingNumChars <= minWidthCharacters && (
128+
129+
{position === TruncatePosition.middle && trailingNumChars === 0 && (
128130
<React.Fragment>
129131
<span ref={textRef} className={styles.truncateStart}>
130-
{content}
132+
{sliceContent(content, 0)[0]}
131133
</span>
134+
<span className={styles.truncateEnd}>{sliceContent(content, 0)[1]}</span>
132135
</React.Fragment>
133136
)}
137+
{position === TruncatePosition.middle &&
138+
trailingNumChars > 0 &&
139+
content.length - trailingNumChars > minWidthCharacters && (
140+
<React.Fragment>
141+
<span ref={textRef} className={styles.truncateStart}>
142+
{sliceContent(content, trailingNumChars)[0]}
143+
</span>
144+
<span className={styles.truncateEnd}>{sliceContent(content, trailingNumChars)[1]}</span>
145+
</React.Fragment>
146+
)}
147+
{position === TruncatePosition.middle &&
148+
trailingNumChars > 0 &&
149+
content.length - trailingNumChars <= minWidthCharacters && (
150+
<React.Fragment>
151+
<span ref={textRef} className={styles.truncateStart}>
152+
{content}
153+
</span>
154+
</React.Fragment>
155+
)}
134156
</span>
135157
);
136158

packages/react-core/src/components/Truncate/__tests__/Truncate.test.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,24 @@ test('renders different content when trailingNumChars is passed with middle trun
113113
expect(end).toHaveClass(styles.truncateEnd);
114114
});
115115

116+
test('renders different content when trailingNumChars is passed 0 for true middle truncation', () => {
117+
render(
118+
<Truncate
119+
content={'Vestibulum interdum risus et enim faucibus, sit amet molestie est accumsan.'} // 75 chars
120+
trailingNumChars={0}
121+
position="middle"
122+
/>
123+
);
124+
125+
const start = screen.getByText('Vestibulum interdum risus et enim fau');
126+
127+
expect(start).toHaveClass(styles.truncateStart);
128+
129+
const end = screen.getByText('cibus, sit amet molestie est accumsan.');
130+
131+
expect(end).toHaveClass(styles.truncateEnd);
132+
});
133+
116134
test('renders full content when trailingNumChars exceeds the length of the original string using middle truncate', () => {
117135
render(
118136
<Truncate

packages/react-core/src/components/Truncate/examples/Truncate.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ import { Truncate } from '@patternfly/react-core';
2828

2929
<div className="truncate-example-resize">
3030
<Truncate
31-
content={'redhat_logo_black_and_white_reversed_simple_with_fedora_container.zip'}
32-
trailingNumChars={10}
31+
content={'rh_logo_black_and_white_reversed_fedora_container.zip'}
32+
trailingNumChars={0}
3333
position={'middle'}
3434
/>
3535
</div>

0 commit comments

Comments
 (0)