diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/README.md b/packages/web-react/src/components/UNSTABLE_Truncate/README.md
new file mode 100644
index 0000000000..e09ef09a6d
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/README.md
@@ -0,0 +1,36 @@
+# UNSTABLE Truncate
+
+> ⚠️ This component is UNSTABLE. It may significantly change at any point in the future.
+> Please use it with caution.
+
+Truncate is a component that truncates text based on defined number of rows.
+
+```jsx
+import { UNSTABLE_Truncate } from '@lmc-eu/spirit-web-react';
+
+{/* Text go here */};
+```
+
+## Lines
+
+You can add the number of lines to which you want to truncate the text using `lines` props
+
+```jsx
+{/* Text go here */}
+```
+
+## API
+
+| Name | Type | Default | Required | Description |
+| ------------- | ----------------------- | ------- | -------- | -------------------------------------------------- |
+| `children` | `string` \| `ReactNode` | `null` | ✓ | Content of the Truncate |
+| `elementType` | `ElementType` | `span` | ✕ | Type of element used |
+| `lines` | `number` | 3 | ✕ | The number of lines on which the text is truncated |
+
+The components accept [additional attributes][readme-additional-attributes].
+If you need more control over the styling of a component, you can use [style props][readme-style-props]
+and [escape hatches][readme-escape-hatches].
+
+[readme-additional-attributes]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#additional-attributes
+[readme-escape-hatches]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#escape-hatches
+[readme-style-props]: https://github.com/lmc-eu/spirit-design-system/blob/main/packages/web-react/README.md#style-props
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/UNSTABLE_Truncate.tsx b/packages/web-react/src/components/UNSTABLE_Truncate/UNSTABLE_Truncate.tsx
new file mode 100644
index 0000000000..447e33d11f
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/UNSTABLE_Truncate.tsx
@@ -0,0 +1,36 @@
+import classNames from 'classnames';
+import React, { ElementType } from 'react';
+import { useClassNamePrefix, useStyleProps } from '../../hooks';
+import { SpiritTruncateProps } from '../../types/truncate';
+import { useTruncateStyleProps } from './useTruncateStyleProps';
+
+const defaultProps = {
+ elementType: 'span',
+};
+
+const UNSTABLE_Truncate = (props: SpiritTruncateProps): JSX.Element => {
+ const propsWithDefaults = { ...defaultProps, ...props };
+ const { children, elementType: ElementTag = 'span', ...restProps } = propsWithDefaults;
+
+ const { classProps, props: modifiedProps, styleProps: truncateStyle } = useTruncateStyleProps(restProps);
+ const { styleProps, props: otherProps } = useStyleProps(modifiedProps);
+
+ const truncateStyleProps = {
+ style: {
+ ...styleProps.style,
+ ...truncateStyle,
+ },
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export default UNSTABLE_Truncate;
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/__tests__/UNSTABLE_Truncate.test.tsx b/packages/web-react/src/components/UNSTABLE_Truncate/__tests__/UNSTABLE_Truncate.test.tsx
new file mode 100644
index 0000000000..e05eb208e5
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/__tests__/UNSTABLE_Truncate.test.tsx
@@ -0,0 +1,41 @@
+import '@testing-library/jest-dom';
+import { render, screen } from '@testing-library/react';
+import React from 'react';
+import { classNamePrefixProviderTest } from '../../../../tests/providerTests/classNamePrefixProviderTest';
+import { restPropsTest } from '../../../../tests/providerTests/restPropsTest';
+import { stylePropsTest } from '../../../../tests/providerTests/stylePropsTest';
+import UNSTABLE_Truncate from '../UNSTABLE_Truncate';
+
+describe('UNSTABLE_Truncate', () => {
+ classNamePrefixProviderTest(UNSTABLE_Truncate, 'text-truncate-multiline');
+
+ stylePropsTest(UNSTABLE_Truncate);
+
+ restPropsTest(UNSTABLE_Truncate, 'span');
+
+ it('should have default classname', () => {
+ render(Text content);
+
+ expect(screen.getByText('Text content')).toHaveClass('text-truncate-multiline');
+ });
+
+ it('should have correct style based on lines', () => {
+ render(Text content);
+ const text = screen.getByText('Text content');
+
+ expect(text).toHaveClass('text-truncate-multiline');
+ expect(text).toHaveStyle('--text-truncate-lines:2;');
+ });
+
+ it('should render children', () => {
+ render(Text content);
+
+ expect(screen.getByText('Text content')).toBeInTheDocument();
+ });
+
+ it('should render with custom elementType', () => {
+ render(Text content);
+
+ expect(screen.getByText('Text content')).toContainHTML('h2');
+ });
+});
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/__tests__/useTruncateStyleProps.test.ts b/packages/web-react/src/components/UNSTABLE_Truncate/__tests__/useTruncateStyleProps.test.ts
new file mode 100644
index 0000000000..6616f9d70e
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/__tests__/useTruncateStyleProps.test.ts
@@ -0,0 +1,19 @@
+import { renderHook } from '@testing-library/react';
+import { useTruncateStyleProps } from '../useTruncateStyleProps';
+
+describe('useTruncateStyleProps', () => {
+ it('should return defaults', () => {
+ const props = {};
+ const { result } = renderHook(() => useTruncateStyleProps(props));
+
+ expect(result.current.classProps).toBe('text-truncate-multiline');
+ });
+
+ it('should return correct style based on lines', () => {
+ const props = { lines: 2 };
+ const { result } = renderHook(() => useTruncateStyleProps(props));
+
+ expect(result.current.classProps).toBe('text-truncate-multiline');
+ expect(result.current.styleProps).toEqual({ '--text-truncate-lines': 2 });
+ });
+});
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/demo/TruncateDefault.tsx b/packages/web-react/src/components/UNSTABLE_Truncate/demo/TruncateDefault.tsx
new file mode 100644
index 0000000000..3532a7fe26
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/demo/TruncateDefault.tsx
@@ -0,0 +1,48 @@
+import React, { useState } from 'react';
+import { TextField } from '../../TextField';
+import UNSTABLE_Truncate from '../UNSTABLE_Truncate';
+
+const TruncateDefault = () => {
+ const [lines, setLines] = useState(3);
+
+ return (
+ <>
+
+
+ Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam quis nulla. Vivamus ac leo pretium faucibus.
+ Pellentesque pretium lectus id turpis. Maecenas lorem. Maecenas sollicitudin. Nullam justo enim, consectetuer
+ nec, ullamcorper ac, vestibulum in, elit. Sed ut perspiciatis unde omnis iste natus error sit voluptatem
+ accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi
+ architecto beatae vitae dicta sunt explicabo. Suspendisse sagittis ultrices augue. Aenean fermentum risus id
+ tortor. Etiam bibendum elit eget erat. Nulla quis diam. Donec iaculis gravida nulla. Nulla pulvinar eleifend
+ sem. Fusce aliquam vestibulum ipsum. Sed ac dolor sit amet purus malesuada congue. In dapibus augue non sapien.
+ Morbi imperdiet, mauris ac auctor dictum, nisl ligula egestas nulla, et sollicitudin sem purus in lacus. Nam sed
+ tellus id magna elementum tincidunt. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam quis nulla.
+ Vivamus ac leo pretium faucibus. Pellentesque pretium lectus id turpis. Maecenas lorem. Maecenas sollicitudin.
+ Nullam justo enim, consectetuer nec, ullamcorper ac, vestibulum in, elit. Sed ut perspiciatis unde omnis iste
+ natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo
+ inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Suspendisse sagittis ultrices augue.
+ Aenean fermentum risus id tortor. Etiam bibendum elit eget erat. Nulla quis diam. Donec iaculis gravida nulla.
+ Nulla pulvinar eleifend sem. Fusce aliquam vestibulum ipsum. Sed ac dolor sit amet purus malesuada congue. In
+ dapibus augue non sapien. Morbi imperdiet, mauris ac auctor dictum, nisl ligula egestas nulla, et sollicitudin
+ sem purus in lacus. Nam sed tellus id magna elementum tincidunt.
+
+ >
+ );
+};
+
+export default TruncateDefault;
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/demo/index.tsx b/packages/web-react/src/components/UNSTABLE_Truncate/demo/index.tsx
new file mode 100644
index 0000000000..2eb69a61df
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/demo/index.tsx
@@ -0,0 +1,12 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import DocsSection from '../../../../docs/DocsSections';
+import TruncateDefault from './TruncateDefault';
+
+ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
+
+
+
+
+ ,
+);
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/index.html b/packages/web-react/src/components/UNSTABLE_Truncate/index.html
new file mode 100644
index 0000000000..23972ef557
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/index.html
@@ -0,0 +1 @@
+{{> web-react/demo}}
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/index.ts b/packages/web-react/src/components/UNSTABLE_Truncate/index.ts
new file mode 100644
index 0000000000..9a7354262a
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/index.ts
@@ -0,0 +1,3 @@
+export * from './UNSTABLE_Truncate';
+export * from './useTruncateStyleProps';
+export { default as UNSTABLE_Truncate } from './UNSTABLE_Truncate';
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/stories/UNSTABLE_Truncate.stories.tsx b/packages/web-react/src/components/UNSTABLE_Truncate/stories/UNSTABLE_Truncate.stories.tsx
new file mode 100644
index 0000000000..15bdd0aba1
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/stories/UNSTABLE_Truncate.stories.tsx
@@ -0,0 +1,45 @@
+import { Markdown } from '@storybook/blocks';
+import type { Meta, StoryObj } from '@storybook/react';
+import React from 'react';
+import ReadMe from '../README.md';
+import UNSTABLE_Truncate from '../UNSTABLE_Truncate';
+
+const meta: Meta = {
+ title: 'Experimental/UNSTABLE_Truncate',
+ component: UNSTABLE_Truncate,
+ parameters: {
+ docs: {
+ page: () => {ReadMe},
+ },
+ },
+ argTypes: {
+ children: {
+ control: 'text',
+ },
+ lines: {
+ control: 'number',
+ table: {
+ defaultValue: { summary: '3' },
+ },
+ },
+ },
+ args: {
+ children:
+ 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam quis nulla. Vivamus ac leo pretium faucibus.\n' +
+ 'Pellentesque pretium lectus id turpis. Maecenas lorem. Maecenas sollicitudin. Nullam justo enim, consectetuer nec,\n' +
+ 'ullamcorper ac, vestibulum in, elit. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium\n' +
+ 'doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae\n' +
+ 'vitae dicta sunt explicabo. Suspendisse sagittis ultrices augue. Aenean fermentum risus id tortor. Etiam bibendum\n' +
+ 'elit eget erat. Nulla quis diam. Donec iaculis gravida nulla. Nulla pulvinar eleifend sem. Fusce aliquam vestibulum\n' +
+ 'ipsum. Sed ac dolor sit amet purus malesuada congue. In dapibus augue non sapien. Morbi imperdiet, mauris ac auctor\n' +
+ 'dictum, nisl ligula egestas nulla, et sollicitudin sem purus in lacus. Nam sed tellus id magna elementum tincidunt.',
+ lines: 3,
+ },
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Playground: Story = {
+ name: 'UNSTABLE_Truncate',
+};
diff --git a/packages/web-react/src/components/UNSTABLE_Truncate/useTruncateStyleProps.ts b/packages/web-react/src/components/UNSTABLE_Truncate/useTruncateStyleProps.ts
new file mode 100644
index 0000000000..cef6991a86
--- /dev/null
+++ b/packages/web-react/src/components/UNSTABLE_Truncate/useTruncateStyleProps.ts
@@ -0,0 +1,28 @@
+import { CSSProperties, ElementType } from 'react';
+import { SpiritTruncateProps } from '../../types/truncate';
+
+interface TruncateCSSProperties extends CSSProperties {
+ '--text-truncate-lines'?: number;
+}
+
+export interface TruncateStyles {
+ classProps: string;
+ props: SpiritTruncateProps;
+ styleProps: TruncateCSSProperties;
+}
+
+export function useTruncateStyleProps(props: SpiritTruncateProps): TruncateStyles {
+ const { lines, ...restProps } = props;
+
+ const TruncateMultilinesClass = 'text-truncate-multiline';
+ const classProps = TruncateMultilinesClass;
+
+ const truncateStyle: TruncateCSSProperties = {};
+ truncateStyle['--text-truncate-lines'] = lines;
+
+ return {
+ classProps,
+ props: restProps,
+ styleProps: truncateStyle,
+ };
+}
diff --git a/packages/web-react/src/types/truncate.ts b/packages/web-react/src/types/truncate.ts
new file mode 100644
index 0000000000..8aada1338f
--- /dev/null
+++ b/packages/web-react/src/types/truncate.ts
@@ -0,0 +1,8 @@
+import { ElementType } from 'react';
+import { ChildrenProps, StyleProps } from './shared';
+
+export type SpiritTruncateProps = {
+ elementType?: E;
+ lines?: number;
+} & StyleProps &
+ ChildrenProps;
diff --git a/tests/e2e/demo-components-compare.spec.ts-snapshots/unstable-truncate-chromium-linux.png b/tests/e2e/demo-components-compare.spec.ts-snapshots/unstable-truncate-chromium-linux.png
new file mode 100644
index 0000000000..c6032ed0eb
Binary files /dev/null and b/tests/e2e/demo-components-compare.spec.ts-snapshots/unstable-truncate-chromium-linux.png differ
diff --git a/tests/e2e/demo-homepages.spec.ts-snapshots/web-react-chromium-linux.png b/tests/e2e/demo-homepages.spec.ts-snapshots/web-react-chromium-linux.png
index d2935d1d0e..8b405c1c33 100644
Binary files a/tests/e2e/demo-homepages.spec.ts-snapshots/web-react-chromium-linux.png and b/tests/e2e/demo-homepages.spec.ts-snapshots/web-react-chromium-linux.png differ