Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4382,6 +4382,7 @@ describe('AnalyticalTable', () => {
.should('have.prop', 'scrollTop', 3000);
cy.get('[data-component-name="AnalyticalTableBody"]').should('have.prop', 'scrollTop', 3000);

cy.wait(100);
cy.get('[data-component-name="AnalyticalTableContainerWithScrollbar"]').realMouseWheel({ deltaY: 500 });
cy.get('[data-component-name="AnalyticalTableBody"]').should('have.prop', 'scrollTop', 3500);
cy.get('[data-component-name="AnalyticalTableVerticalScrollbar"]').should('have.prop', 'scrollTop', 3500);
Expand Down
70 changes: 35 additions & 35 deletions packages/main/src/components/AnalyticalTable/AnalyticalTable.mdx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@
}

.tr {
height: var(--_ui5wcr_AnalyticalTable_RowHeight);
position: absolute;
inset-block-start: 0;
inset-inline-start: 0;
Expand Down Expand Up @@ -226,12 +227,12 @@
display: block;
}

.tableText {
/* PUBLIC: When removed or changed, first check if custom inline Cell content is still truncated (Recipes) */
.textEllipsis {
display: inline-block;
font-size: var(--sapFontSize);
max-width: 100%;
box-sizing: border-box;
font-weight: normal;
overflow: hidden;
word-wrap: normal;
white-space: nowrap;
Expand Down Expand Up @@ -266,6 +267,12 @@
&[aria-selected='true']:not([data-empty-row-cell]):focus::after {
inset-block-end: 2px;
}

/* Make ellipsis work for text-only content */
&:not(:has(*)) {
display: block;
line-height: var(--_ui5wcr_AnalyticalTable_RowHeight);
}
}

.showVerticalEndBorder .tableCell {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,3 +663,42 @@ export const KitchenSink: Story = {
return context.viewMode === 'story' ? <AnalyticalTable {...args} /> : <ToggleableTable {...args} />;
},
};

// ===================== Not displayed in sidebar & tags popover =====================

export const EllipsisExamples: Story = {
tags: ['excludeFromSidebar'],
args: {
data: dataLarge.slice(0, 5),
columns: [
{
Header: 'Plain String (Automatic Ellipsis)',
accessor: 'name',
width: 60,
Cell: ({ value }) => value,
},
{
Header: 'With textEllipsis Class',
accessor: 'friend.name',
width: 60,
Cell: ({ value, webComponentsReactProperties }) => (
<div className={webComponentsReactProperties.classes.textEllipsis} title={value}>
{value}
</div>
),
},
{
Header: 'With Text Component',
id: 'description',
width: 60,
Cell: () => (
<Text maxLines={1} title="This is a very long text that demonstrates how the Text component handles ellipsis">
This is a very long text that demonstrates how the Text component handles ellipsis
</Text>
),
},
],
visibleRows: 5,
style: { width: 'min(100%, 300px)' },
},
};
82 changes: 80 additions & 2 deletions packages/main/src/components/AnalyticalTable/Recipes.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { TableOfContent } from '@sb/components';
import { Meta } from '@storybook/addon-docs/blocks';
import { Meta, Canvas } from '@storybook/addon-docs/blocks';
import { Footer } from '@sb/components';
import { MessageStrip } from '../../webComponents/index';
import { MessageStrip } from '../../webComponents/MessageStrip/index';
import * as ComponentStories from './AnalyticalTable.stories';

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

Expand Down Expand Up @@ -367,4 +368,81 @@ To initially select or expand a row; reorder, filter, group, hide or sort a colu
/>
```

## How to show ellipsis for custom Cells?

**Applicable since v2.16.1**

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.

### Automatic Ellipsis (Plain Strings)

If your custom `Cell` renderer returns a plain string, ellipsis is ensured automatically:

```jsx
const columns = [
{
Header: 'Name',
accessor: 'name',
Cell: ({ value }) => value // Plain string - ellipsis works automatically
},
];
```

### Manual Ellipsis (Custom Elements)

When rendering custom elements, you need to apply ellipsis styling:

#### Inline Content

Use the `webComponentsReactProperties.classes.textEllipsis` class for inline content that should truncate with ellipsis:

```jsx
const columns = [
{
Header: 'Name',
accessor: 'name',
Cell: ({ value, webComponentsReactProperties }) => (
<span
className={webComponentsReactProperties.classes.textEllipsis}
title={value} // Show full text on hover
>
{value}
</span>
),
},
];
```

#### For Web Components with Built-in Text Handling

Some Web Components like `Text` and `Label` handle text truncation internally and don't require the `textEllipsis` class:

```jsx
import { Text } from '@ui5/webcomponents-react';

const columns = [
{
Header: 'Description',
accessor: 'description',
Cell: ({ value }) => (
<Text maxLines={1}>{value}</Text> // Text component handles ellipsis internally
),
},
];
```

#### For Other Custom Components

For multi-line content or custom components that don't handle ellipsis, truncation must be ensured by defining the styles yourself.

### Example

<details>
<summary>Show Example</summary>
<Canvas of={ComponentStories.EllipsisExamples} />
</details>

<br />
<br />

<Footer />
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export const VirtualTableBody = (props: VirtualTableBodyProps) => {
transform: `translateY(${virtualRow.start}px)`,
position: 'absolute',
boxSizing: 'border-box',
height: `${updatedHeight}px`,
'--_ui5wcr_AnalyticalTable_RowHeight': `${updatedHeight}px`,
}}
>
{typeof renderRowSubComponent === 'function' && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const Cell = (props: CellInstance) => {
<span
id={`${webComponentsReactProperties.uniqueId}${column.id}${row.id}`}
title={cellContent}
className={webComponentsReactProperties.classes.tableText}
className={webComponentsReactProperties.classes.textEllipsis}
data-column-id-cell-text={column.id}
// 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
aria-hidden="true"
Expand Down
7 changes: 4 additions & 3 deletions packages/main/src/components/AnalyticalTable/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,11 @@ export interface AnalyticalTableColumnDefinition {
headerTooltip?: string;
/**
* Custom cell renderer. If set, the table will use this component or render the provided string for every cell,
* passing all necessary information as props, e.g., the cell value as `props.cell.value`.
* passing all necessary information as props, e.g., the cell value as `props.value`.
*
* __Note:__ Using a custom component __can impact performance__!
* If you pass a component, __memoizing it is strongly recommended__, especially for complex components or large datasets.
* __Note:__
* - Using a custom component __can impact performance__! If you pass a component, __memoizing it is strongly recommended__, especially for complex components or large datasets.
* - 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.
*/
Cell?: string | ComponentType<CellInstance>;
/**
Expand Down
Loading