Skip to content

Commit 7ab5130

Browse files
committed
fix(AnalyticalTable): text ellipsis for strings & class for elements for custom Cell
1 parent b722ccf commit 7ab5130

File tree

6 files changed

+132
-10
lines changed

6 files changed

+132
-10
lines changed

packages/main/src/components/AnalyticalTable/AnalyticalTable.module.css

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
}
156156

157157
.tr {
158+
height: var(--_ui5wcr_AnalyticalTable_RowHeight);
158159
position: absolute;
159160
inset-block-start: 0;
160161
inset-inline-start: 0;
@@ -226,12 +227,12 @@
226227
display: block;
227228
}
228229

229-
.tableText {
230+
/* PUBLIC: When removed or changed, first check if custom inline Cell content is still truncated (Recipes) */
231+
.textEllipsis {
230232
display: inline-block;
231233
font-size: var(--sapFontSize);
232234
max-width: 100%;
233235
box-sizing: border-box;
234-
font-weight: normal;
235236
overflow: hidden;
236237
word-wrap: normal;
237238
white-space: nowrap;
@@ -266,6 +267,12 @@
266267
&[aria-selected='true']:not([data-empty-row-cell]):focus::after {
267268
inset-block-end: 2px;
268269
}
270+
271+
/* Make ellipsis work for text-only content */
272+
&:not(:has(*)) {
273+
display: block;
274+
line-height: var(--_ui5wcr_AnalyticalTable_RowHeight);
275+
}
269276
}
270277

271278
.showVerticalEndBorder .tableCell {

packages/main/src/components/AnalyticalTable/AnalyticalTable.stories.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,3 +663,42 @@ export const KitchenSink: Story = {
663663
return context.viewMode === 'story' ? <AnalyticalTable {...args} /> : <ToggleableTable {...args} />;
664664
},
665665
};
666+
667+
// ===================== Not displayed in sidebar & tags popover =====================
668+
669+
export const EllipsisExamples: Story = {
670+
tags: ['excludeFromSidebar'],
671+
args: {
672+
data: dataLarge.slice(0, 5),
673+
columns: [
674+
{
675+
Header: 'Plain String (Automatic Ellipsis)',
676+
accessor: 'name',
677+
width: 60,
678+
Cell: ({ value }) => value,
679+
},
680+
{
681+
Header: 'With textEllipsis Class',
682+
accessor: 'friend.name',
683+
width: 60,
684+
Cell: ({ value, webComponentsReactProperties }) => (
685+
<div className={webComponentsReactProperties.classes.textEllipsis} title={value}>
686+
{value}
687+
</div>
688+
),
689+
},
690+
{
691+
Header: 'With Text Component',
692+
id: 'description',
693+
width: 60,
694+
Cell: () => (
695+
<Text maxLines={1} title="This is a very long text that demonstrates how the Text component handles ellipsis">
696+
This is a very long text that demonstrates how the Text component handles ellipsis
697+
</Text>
698+
),
699+
},
700+
],
701+
visibleRows: 5,
702+
style: { width: 'min(100%, 300px)' },
703+
},
704+
};

packages/main/src/components/AnalyticalTable/Recipes.mdx

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { TableOfContent } from '@sb/components';
2-
import { Meta } from '@storybook/addon-docs/blocks';
2+
import { Meta, Canvas } from '@storybook/addon-docs/blocks';
33
import { Footer } from '@sb/components';
4-
import { MessageStrip } from '../../webComponents/index';
4+
import { MessageStrip } from '../../webComponents/MessageStrip/index';
5+
import * as ComponentStories from './AnalyticalTable.stories';
56

67
<Meta title="Data Display / AnalyticalTable / Recipes" />
78

@@ -367,4 +368,79 @@ To initially select or expand a row; reorder, filter, group, hide or sort a colu
367368
/>
368369
```
369370

371+
## How to show ellipsis for custom Cells?
372+
373+
When using custom `Cell` renderers, text truncation with ellipsis works automatically if you return a plain string. However, when rendering custom content, you need to handle ellipsis styling yourself.
374+
375+
### Automatic Ellipsis (Plain Strings)
376+
377+
If your custom `Cell` renderer returns a plain string, ellipsis is ensured automatically:
378+
379+
```jsx
380+
const columns = [
381+
{
382+
Header: 'Name',
383+
accessor: 'name',
384+
Cell: ({ value }) => value // Plain string - ellipsis works automatically
385+
},
386+
];
387+
```
388+
389+
### Manual Ellipsis (Custom Elements)
390+
391+
When rendering custom elements, you need to apply ellipsis styling:
392+
393+
#### Inline Content
394+
395+
Use the `webComponentsReactProperties.classes.textEllipsis` class for inline content that should truncate with ellipsis:
396+
397+
```jsx
398+
const columns = [
399+
{
400+
Header: 'Name',
401+
accessor: 'name',
402+
Cell: ({ value, webComponentsReactProperties }) => (
403+
<span
404+
className={webComponentsReactProperties.classes.textEllipsis}
405+
title={value} // Show full text on hover
406+
>
407+
{value}
408+
</span>
409+
),
410+
},
411+
];
412+
```
413+
414+
#### For Web Components with Built-in Text Handling
415+
416+
Some Web Components like `Text` and `Label` handle text truncation internally and don't require the `textEllipsis` class:
417+
418+
```jsx
419+
import { Text } from '@ui5/webcomponents-react';
420+
421+
const columns = [
422+
{
423+
Header: 'Description',
424+
accessor: 'description',
425+
Cell: ({ value }) => (
426+
<Text maxLines={1}>{value}</Text> // Text component handles ellipsis internally
427+
),
428+
},
429+
];
430+
```
431+
432+
#### For Other Custom Components
433+
434+
For multi-line content or custom components that don't handle ellipsis, truncation must be ensured by defining the styles yourself.
435+
436+
### Example
437+
438+
<details>
439+
<summary>Show Example</summary>
440+
<Canvas of={ComponentStories.EllipsisExamples} />
441+
</details>
442+
443+
<br />
444+
<br />
445+
370446
<Footer />

packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBody.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
199199
transform: `translateY(${virtualRow.start}px)`,
200200
position: 'absolute',
201201
boxSizing: 'border-box',
202-
height: `${updatedHeight}px`,
202+
'--_ui5wcr_AnalyticalTable_RowHeight': `${updatedHeight}px`,
203203
}}
204204
>
205205
{typeof renderRowSubComponent === 'function' && (
@@ -235,7 +235,6 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
235235
position: 'absolute',
236236
width: `${virtualColumn.size}px`,
237237
top: 0,
238-
height: `${rowHeight}px`,
239238
...getDirectionStyles(isRtl, virtualColumn),
240239
},
241240
};

packages/main/src/components/AnalyticalTable/defaults/Column/Cell.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const Cell = (props: CellInstance) => {
1616
<span
1717
id={`${webComponentsReactProperties.uniqueId}${column.id}${row.id}`}
1818
title={cellContent}
19-
className={webComponentsReactProperties.classes.tableText}
19+
className={webComponentsReactProperties.classes.textEllipsis}
2020
data-column-id-cell-text={column.id}
2121
// VoiceOver announces blank because of `aria-hidden` although `aria-labelledby` is set on the `gridcell` element - this is a known bug and there's no workaround
2222
aria-hidden="true"

packages/main/src/components/AnalyticalTable/types/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,11 @@ export interface AnalyticalTableColumnDefinition {
455455
headerTooltip?: string;
456456
/**
457457
* Custom cell renderer. If set, the table will use this component or render the provided string for every cell,
458-
* passing all necessary information as props, e.g., the cell value as `props.cell.value`.
458+
* passing all necessary information as props, e.g., the cell value as `props.value`.
459459
*
460-
* __Note:__ Using a custom component __can impact performance__!
461-
* If you pass a component, __memoizing it is strongly recommended__, especially for complex components or large datasets.
460+
* __Note:__
461+
* - Using a custom component __can impact performance__! If you pass a component, __memoizing it is strongly recommended__, especially for complex components or large datasets.
462+
* - For custom elements, text truncation needs to be applied manually. [Here](https://ui5.github.io/webcomponents-react/v2/?path=/docs/data-display-analyticaltable-recipes--docs) you can find out more.
462463
*/
463464
Cell?: string | ComponentType<CellInstance>;
464465
/**

0 commit comments

Comments
 (0)