diff --git a/packages/main/src/components/AnalyticalTable/AnalyticalTable.cy.tsx b/packages/main/src/components/AnalyticalTable/AnalyticalTable.cy.tsx
index 1882cad8dd7..ea9f81e9c92 100644
--- a/packages/main/src/components/AnalyticalTable/AnalyticalTable.cy.tsx
+++ b/packages/main/src/components/AnalyticalTable/AnalyticalTable.cy.tsx
@@ -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);
diff --git a/packages/main/src/components/AnalyticalTable/AnalyticalTable.mdx b/packages/main/src/components/AnalyticalTable/AnalyticalTable.mdx
index 77baf0faf0e..8c768f75645 100644
--- a/packages/main/src/components/AnalyticalTable/AnalyticalTable.mdx
+++ b/packages/main/src/components/AnalyticalTable/AnalyticalTable.mdx
@@ -97,41 +97,41 @@ const TableComp = () => {
**Optional Properties**
-| Attribute | Type | Description |
-| ----------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `Header` | `string OR ComponentType` | Can either be `string` or a React component that will be rendered as column header |
-| `headerLabel` | `string` | Defines the `aria-label` for the whole column read by screen readers. |
-| `headerTooltip` | `string` | Tooltip for the column header. If not set, the display text will be the same as the Header if it is a `string` |
-| `Cell` | `ComponentType` | Custom cell renderer. If set, the table will call that component for every cell and pass all required information as props, e.g. the cell value as `props.cell.value` |
-| `cellLabel` | `({cell, instance}) => string` | Defines a function that receives an object as a parameter, including the cell and table instance, and should return the `aria-label` of the current cell.
**Note:** Use this property if there is no textual content available through the dataset (e.g. no `accessor` field available), or if you want to provide additional context when navigating to the respective cell for screen readers.
**Note:** To retrieve the internal `aria-label`, utilize the `cell.cellLabel` property. |
-| `width` | `number` | Defines the column width. If not set, the table will distribute all columns without a width evenly.
**Note:** Values lower than `minWidth` are not supported! |
-| `minWidth` | `number` | Minimum width of the column.
**Default:** `60` |
-| `maxWidth` | `number` | Maximum width of the column. |
-| `Filter` | `ComponentType` | Filter Component to be rendered in the Header |
-| `disableFilters` | `boolean` | Disable filters for this column |
-| `disableGlobalFilter` | `boolean` | Disable global filtering for this column |
-| `defaultCanFilter` | `boolean` | If set to true, this column will be filterable, regardless if it has a valid `accessor` |
-| `filter` | `string OR Function` | Either a string or a filter function.
Supported String Values:
- `text`
- `exactText`
- `exactTextCase`
- `equals`
**Note:** When the standard `Filter` component is used, the filter function is not triggered if the `filterValue` is empty, as the filter is then removed. |
-| `Aggregated` | `ComponentType` | Component to render for aggregated cells |
-| `aggregate` | `string` OR
`((leafValues, aggregatedValues) => any)` | Aggregation function or string.
Supported String Values: - `sum`
- `min`
- `max`
- `minMax`
- `average`
- `median`
- `unique`
- `uniqueCount`
- `count`
|
-| `aggregateValue` | `string` OR
`((values, row, column) => any)` | When attempting to group/aggregate non primitive cell values (eg. arrays of items) you will likely need to resolve a stable primitive value like a number or string to use in normal row aggregations. This property can be used to aggregate or simply access the value to be used in aggregations eg. count-ing the unique number of items in a cell's array value before sum-ing that count across the table |
-| `disableGroupBy` | `boolean` | Disable groupBy for this column |
-| `defaultCanSort` | `boolean` | If set to true, this column will be sortable, regardless if it has a valid `accessor` |
-| `disableSortBy` | `boolean` | Disable sorting for this column |
-| `sortDescFirst` | `boolean` | If set to `true`, the first sort direction for this column will be descending instead of ascending. |
-| `sortInverted` | `boolean` | If set to `true`, the underlying sorting direction will be inverted, but the UI will not. |
-| `sortType` | `string` OR
`((rowA, rowB, columnId: string, descending: boolean)`
`=> number)` | String or custom **memoized** sort function.
Supported String Values: - `basic`
- `datetime`
- `alphanumeric`
**Default:**`'alphanumeric'` |
-| `disableResizing` | `boolean` | Disable resizing for this column |
-| `hAlign` | `TextAlign` | Horizontal align of the cell |
-| `vAlign` | `VerticalAlign` | Vertical align of the cell |
-| `scaleWidthModeOptions` | `ScaleWidthModeOptions` | Allows passing a custom string for the internal width calculation of custom cells for `scaleWidthMode` `Grow` and `Smart`. More here |
-| `responsivePopIn` | `boolean` | Enables the pop-in behavior of the column. When the `responsiveMinWidth` is smaller then the width of the table, the content of each cell will move to the first cell in the row, improving usability on small or mobile devices.
**Note:** At least one column must remain visible at all times! |
-| `responsiveMinWidth` | `number` | Defines how the table should react when its width falls below the `responsiveMinWidth`. - If `responsivePopIn` is `true` the content of this column will be moved to the first column.
- If `responsivePopIn` is not set or `false` the column will be hidden.
|
-| `PopInHeader` | `string OR ComponentType` | Custom pop-in header renderer. If set, the table will call that component for every column that is "popped-in" and pass the table instance as prop. |
-| `popinDisplay` | `AnalyticalTablePopinDisplay` | Defines the display of `AnalyticalTable` pop-ins.
**Default:** `AnalyticalTablePopinDisplay.Block` |
-| `disableDragAndDrop` | `boolean` | Defines if the column is reorderable by dragging and dropping columns. |
-| `enableMultiSort` | `boolean` | Defines whether this column should allow multi-sort.
**Note:** When sorting by a column that does not allow multiple sorting, only the current column is sorted and all other sorted columns are reset. |
-| `autoResizable` | `boolean` | Defines whether double-clicking a columns resizer will automatically resize the column to fit the largest cell content of visible rows.
**Note:** Only default text content is supported by this option, for custom content it might work as well, but we recommend checking the behavior carefully as the logic can't account for all possible implementations. |
+| Attribute | Type | Description |
+| ----------------------- | --------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `Header` | `string` OR
`ComponentType` | Can either be `string` or a React component that will be rendered as column header |
+| `headerLabel` | `string` | Defines the `aria-label` for the whole column read by screen readers. |
+| `headerTooltip` | `string` | Tooltip for the column header. If not set, the display text will be the same as the Header if it is a `string` |
+| `Cell` | `string` OR
`ComponentType`
`` | 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.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.
- 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.
|
+| `cellLabel` | `({cell, instance})`
`=> string` | Defines a function that receives an object as a parameter, including the cell and table instance, and should return the `aria-label` of the current cell.
**Note:** Use this property if there is no textual content available through the dataset (e.g. no `accessor` field available), or if you want to provide additional context when navigating to the respective cell for screen readers.
**Note:** To retrieve the internal `aria-label`, utilize the `cell.cellLabel` property. |
+| `width` | `number` | Defines the column width. If not set, the table will distribute all columns without a width evenly.
**Note:** Values lower than `minWidth` are not supported! |
+| `minWidth` | `number` | Minimum width of the column.
**Default:** `60` |
+| `maxWidth` | `number` | Maximum width of the column. |
+| `Filter` | `ComponentType` | Filter Component to be rendered in the Header |
+| `disableFilters` | `boolean` | Disable filters for this column |
+| `disableGlobalFilter` | `boolean` | Disable global filtering for this column |
+| `defaultCanFilter` | `boolean` | If set to true, this column will be filterable, regardless if it has a valid `accessor` |
+| `filter` | `string OR Function` | Either a string or a filter function.
Supported String Values: - `text`
- `exactText`
- `exactTextCase`
- `equals`
**Note:** When the standard `Filter` component is used, the filter function is not triggered if the `filterValue` is empty, as the filter is then removed. |
+| `Aggregated` | `ComponentType` | Component to render for aggregated cells |
+| `aggregate` | `string` OR
`((leafValues,`
`aggregatedValues)`
`=> any)` | Aggregation function or string.
Supported String Values: - `sum`
- `min`
- `max`
- `minMax`
- `average`
- `median`
- `unique`
- `uniqueCount`
- `count`
|
+| `aggregateValue` | `string` OR
`((values, row,`
`column) => any)` | When attempting to group/aggregate non primitive cell values (eg. arrays of items) you will likely need to resolve a stable primitive value like a number or string to use in normal row aggregations. This property can be used to aggregate or simply access the value to be used in aggregations eg. count-ing the unique number of items in a cell's array value before sum-ing that count across the table |
+| `disableGroupBy` | `boolean` | Disable groupBy for this column |
+| `defaultCanSort` | `boolean` | If set to true, this column will be sortable, regardless if it has a valid `accessor` |
+| `disableSortBy` | `boolean` | Disable sorting for this column |
+| `sortDescFirst` | `boolean` | If set to `true`, the first sort direction for this column will be descending instead of ascending. |
+| `sortInverted` | `boolean` | If set to `true`, the underlying sorting direction will be inverted, but the UI will not. |
+| `sortType` | `string` OR
`((rowA, rowB,`
`columnId: string,`
`descending: boolean)`
`=> number)` | String or custom **memoized** sort function.
Supported String Values: - `basic`
- `datetime`
- `alphanumeric`
**Default:**`'alphanumeric'` |
+| `disableResizing` | `boolean` | Disable resizing for this column |
+| `hAlign` | `TextAlign` | Horizontal align of the cell |
+| `vAlign` | `VerticalAlign` | Vertical align of the cell |
+| `scaleWidthModeOptions` | `ScaleWidthModeOptions` | Allows passing a custom string for the internal width calculation of custom cells for `scaleWidthMode` `Grow` and `Smart`. More here |
+| `responsivePopIn` | `boolean` | Enables the pop-in behavior of the column. When the `responsiveMinWidth` is smaller then the width of the table, the content of each cell will move to the first cell in the row, improving usability on small or mobile devices.
**Note:** At least one column must remain visible at all times! |
+| `responsiveMinWidth` | `number` | Defines how the table should react when its width falls below the `responsiveMinWidth`. - If `responsivePopIn` is `true` the content of this column will be moved to the first column.
- If `responsivePopIn` is not set or `false` the column will be hidden.
|
+| `PopInHeader` | `string` OR
`ComponentType` | Custom pop-in header renderer. If set, the table will call that component for every column that is "popped-in" and pass the table instance as prop. |
+| `popinDisplay` | `AnalyticalTablePopinDisplay` | Defines the display of `AnalyticalTable` pop-ins.
**Default:** `AnalyticalTablePopinDisplay.Block` |
+| `disableDragAndDrop` | `boolean` | Defines if the column is reorderable by dragging and dropping columns. |
+| `enableMultiSort` | `boolean` | Defines whether this column should allow multi-sort.
**Note:** When sorting by a column that does not allow multiple sorting, only the current column is sorted and all other sorted columns are reset. |
+| `autoResizable` | `boolean` | Defines whether double-clicking a columns resizer will automatically resize the column to fit the largest cell content of visible rows.
**Note:** Only default text content is supported by this option, for custom content it might work as well, but we recommend checking the behavior carefully as the logic can't account for all possible implementations. |
diff --git a/packages/main/src/components/AnalyticalTable/AnalyticalTable.module.css b/packages/main/src/components/AnalyticalTable/AnalyticalTable.module.css
index 16be5a4abf7..cea4be59f83 100644
--- a/packages/main/src/components/AnalyticalTable/AnalyticalTable.module.css
+++ b/packages/main/src/components/AnalyticalTable/AnalyticalTable.module.css
@@ -155,6 +155,7 @@
}
.tr {
+ height: var(--_ui5wcr_AnalyticalTable_RowHeight);
position: absolute;
inset-block-start: 0;
inset-inline-start: 0;
@@ -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;
@@ -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 {
diff --git a/packages/main/src/components/AnalyticalTable/AnalyticalTable.stories.tsx b/packages/main/src/components/AnalyticalTable/AnalyticalTable.stories.tsx
index c134c4f082d..12c4fa41936 100644
--- a/packages/main/src/components/AnalyticalTable/AnalyticalTable.stories.tsx
+++ b/packages/main/src/components/AnalyticalTable/AnalyticalTable.stories.tsx
@@ -663,3 +663,42 @@ export const KitchenSink: Story = {
return context.viewMode === 'story' ? : ;
},
};
+
+// ===================== 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 }) => (
+
+ {value}
+
+ ),
+ },
+ {
+ Header: 'With Text Component',
+ id: 'description',
+ width: 60,
+ Cell: () => (
+
+ This is a very long text that demonstrates how the Text component handles ellipsis
+
+ ),
+ },
+ ],
+ visibleRows: 5,
+ style: { width: 'min(100%, 300px)' },
+ },
+};
diff --git a/packages/main/src/components/AnalyticalTable/Recipes.mdx b/packages/main/src/components/AnalyticalTable/Recipes.mdx
index d04356f9011..efc31069db1 100644
--- a/packages/main/src/components/AnalyticalTable/Recipes.mdx
+++ b/packages/main/src/components/AnalyticalTable/Recipes.mdx
@@ -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';
@@ -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 }) => (
+
+ {value}
+
+ ),
+ },
+];
+```
+
+#### 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 }) => (
+ {value} // 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
+
+
+ Show Example
+
+
+
+
+
+
diff --git a/packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBody.tsx b/packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBody.tsx
index caddcc8bca6..105a9476edc 100644
--- a/packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBody.tsx
+++ b/packages/main/src/components/AnalyticalTable/TableBody/VirtualTableBody.tsx
@@ -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' && (
diff --git a/packages/main/src/components/AnalyticalTable/defaults/Column/Cell.tsx b/packages/main/src/components/AnalyticalTable/defaults/Column/Cell.tsx
index 96920bc24c6..082c8b47dad 100644
--- a/packages/main/src/components/AnalyticalTable/defaults/Column/Cell.tsx
+++ b/packages/main/src/components/AnalyticalTable/defaults/Column/Cell.tsx
@@ -16,7 +16,7 @@ export const Cell = (props: CellInstance) => {
;
/**