Skip to content

Commit

Permalink
feat: support multyline and fixed width ellipsis in Text component
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaevAlexandr committed Nov 14, 2023
1 parent 86668fe commit 01df15c
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 24 deletions.
25 changes: 13 additions & 12 deletions src/components/Text/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,16 @@ LANDING_BLOCK-->

## Properties

| Name | Description | Type | Default |
| :--------- | :------------------------------------------------------ | :--------------------------------------: | :--------: |
| children | Text content | `React.ReactNode` | |
| className | HTML `class` attribute | `string` | |
| as | Ability to override default html tag | `React.ElementType<any>` | |
| style | HTML `style` attribute | `React.CSSProperties` | |
| variant | Font of the text | `string` | `"body-1"` |
| ellipsis | Hidden overflow content will be replaced by an ellipsis | `boolean` | |
| whiteSpace | The white-space css property | `"nowrap"` `"break-spaces"` | |
| wordBreak | The word-break css property | `"break-all"` | |
| color | Color of the text | `string` (see values in "Color" section) | |
| ref | | `any` | |
| Name | Description | Type | Default |
| :------------ | :------------------------------------------------------------------------ | :--------------------------------------: | :--------: |
| children | Text content | `React.ReactNode` | |
| className | HTML `class` attribute | `string` | |
| as | Ability to override default html tag | `React.ElementType<any>` | |
| style | HTML `style` attribute | `React.CSSProperties` | |
| variant | Font of the text | `string` | `"body-1"` |
| ellipsis | Hidden overflow content will be replaced by an ellipsis | `boolean` `number` | |
| ellipsisLines | The number of whole lines of text after which the content will be cut off | `2` `3` `4` `5` | |
| whiteSpace | The white-space css property | `"nowrap"` `"break-spaces"` | |
| wordBreak | The word-break css property | `"break-all"` | |
| color | Color of the text | `string` (see values in "Color" section) | |
| ref | | `any` | |
22 changes: 20 additions & 2 deletions src/components/Text/Text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export interface TextProps extends TextBaseProps, ColorTextBaseProps {

type TextRef<C extends React.ElementType> = React.ComponentPropsWithRef<C>['ref'];

type TextPropsWithoutRef<C extends React.ElementType> = {as?: C} & Omit<TextProps, 'as'>;
type TextPropsWithoutRef<C extends React.ElementType> = {
as?: C;
// override only component behavior, cos in inline class utility we have no access to set fixed width to element
ellipsis?: boolean | number;
} & Omit<TextProps, 'as' | 'ellipsis'>;

/**
* A component for working with typography.
Expand Down Expand Up @@ -57,19 +61,33 @@ export const Text = React.forwardRef(
color,
whiteSpace,
wordBreak,
ellipsisLines,
style: outerStyle,
...rest
}: TextPropsWithoutRef<C>,
ref?: TextRef<C>,
) => {
const Tag: React.ElementType = as || 'span';

const style: React.CSSProperties = {
maxWidth: typeof ellipsis === 'number' ? ellipsis : undefined,
...outerStyle,
};

return (
<Tag
ref={ref}
className={text(
{variant, ellipsis, whiteSpace, wordBreak},
{
variant,
ellipsis: Boolean(ellipsis),
ellipsisLines,
whiteSpace,
wordBreak,
},
color ? colorText({color}, className) : className,
)}
style={style}
{...rest}
>
{children}
Expand Down
27 changes: 19 additions & 8 deletions src/components/Text/__stories__/Text.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import React from 'react';

import type {Meta, StoryFn} from '@storybook/react';

import {Text, colorText, text} from '../.';
import type {TextProps} from '../.';
import {Flex} from '../../layout';
import type {TextProps} from '../index';
import {Text, colorText, text} from '../index';

export default {
title: 'Components/Data Display/Text',
Expand All @@ -26,16 +27,26 @@ export const UsingTextUtilities = () => (
</div>
);

const EllipsisDefault: StoryFn<TextProps> = (args) => <Text {...args} />;
const EllipsisDefault: StoryFn<TextProps> = (args) => (
<Flex gap={5}>
<Flex gap={5} width={200} direction="column">
<Text variant="header-1">With fixed container size (ellipsis=true)</Text>
<Text {...args} ellipsis />
</Flex>
<Flex gap={5} direction="column">
<Text variant="header-1">With fixed size ellipsis prop (ellipsis={200})</Text>
<Text {...args} ellipsis={200} />
</Flex>
<Flex gap={5} direction="column">
<Text variant="header-1">With line clamp property (ellipsisLines={3})</Text>
<Text {...args} ellipsisLines={3} />
</Flex>
</Flex>
);

export const Ellipsis = EllipsisDefault.bind({});

Ellipsis.args = {
as: 'div',
ellipsis: true,
style: {
width: 200,
},
children:
'Lorem ipsum dolor sit, amet consectetur adipisicing elit. Voluptates asperiores accusamus est, ab rerum harum hic delectus fuga veniam! Hic, atque, quia sunt consectetur eius corrupti, expedita sapiente exercitationem aperiam quibusdam libero ipsa veritatis quisquam! Debitis eos unde, blanditiis ipsam adipisci, soluta incidunt architecto quidem, repellat commodi tempore! Enim assumenda nam esse laudantium sequi quaerat maiores, voluptatum quibusdam temporibus nulla perspiciatis! Corrupti error aliquid iure asperiores voluptate. Nisi temporibus nesciunt quasi animi, accusamus officia debitis voluptatum ratione ullam delectus, adipisci, repellendus vitae in amet sit magni iste impedit? Exercitationem rerum impedit sed earum iusto modi et officia aspernatur quibusdam? Fugit.',
};
Expand Down
26 changes: 26 additions & 0 deletions src/components/Text/text/text.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,34 @@ $block: '.#{variables.$ns}text';
@include mixins.text-subheader-3();
}
&_ellipsis {
display: inline-block;
@include mixins.overflow-ellipsis();
}

&_ellipsis-lines_2,
&_ellipsis-lines_3,
&_ellipsis-lines_4,
&_ellipsis-lines_5 {
display: -webkit-box; // stylelint-disable-line value-no-vendor-prefix
-webkit-box-orient: vertical;
overflow: hidden;
align-self: center;
white-space: normal;
}

&_ellipsis-lines_2 {
-webkit-line-clamp: 2;
}
&_ellipsis-lines_3 {
-webkit-line-clamp: 3;
}
&_ellipsis-lines_4 {
-webkit-line-clamp: 4;
}
&_ellipsis-lines_5 {
-webkit-line-clamp: 5;
}

&_ws_nowrap {
white-space: nowrap;
}
Expand Down
15 changes: 13 additions & 2 deletions src/components/Text/text/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ export interface TextBaseProps {
* - text-overflow: ellipsis;
*/
ellipsis?: boolean;
/**
* The number of whole lines of text after which the content will be cut off.
*
* !Note: supports only modern browsers
* https://caniuse.com/?search=display%3A%20-webkit-box%3B
*/
ellipsisLines?: 2 | 3 | 4 | 5;
/**
* white-space css property
*/
Expand All @@ -93,6 +100,10 @@ export interface TextBaseProps {
*```
*/
export const text = (
{variant = 'body-1', ellipsis, whiteSpace, wordBreak}: TextBaseProps,
{variant = 'body-1', ellipsis, ellipsisLines, whiteSpace, wordBreak}: TextBaseProps,
className?: string,
) => b({variant, ellipsis, ws: whiteSpace, wb: wordBreak}, className);
) =>
b(
{variant, ellipsis, ws: whiteSpace, wb: wordBreak, 'ellipsis-lines': ellipsisLines},
className,
);

0 comments on commit 01df15c

Please sign in to comment.