Skip to content

Commit 8d25d25

Browse files
authored
feat(css): support for text-overflow (#10369)
1 parent e4fe276 commit 8d25d25

File tree

9 files changed

+120
-12
lines changed

9 files changed

+120
-12
lines changed

apps/toolbox/src/pages/labels.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@
1414
<GridLayout marginTop="10" borderWidth="1" borderColor="#efefef" height="60" paddingLeft="5">
1515
<Label text="Test Label 3: should be aligned top" verticalAlignment="top" />
1616
</GridLayout>
17+
<GridLayout marginTop="10" borderWidth="1" borderColor="#efefef" height="60" paddingLeft="5">
18+
<Label text="Test Label text-overflow: ellipsis, this should be long sentence and clipped at very end." textOverflow="ellipsis" whiteSpace="nowrap" />
19+
</GridLayout>
20+
21+
<GridLayout marginTop="10" borderWidth="1" borderColor="#efefef" height="60" paddingLeft="5">
22+
<Button text="Test Button text-overflow: ellipsis, this should be long sentence and clipped at very end." textOverflow="ellipsis" whiteSpace="nowrap" />
23+
</GridLayout>
24+
25+
<GridLayout marginTop="10" borderWidth="1" borderColor="#efefef" height="60" paddingLeft="5">
26+
<Button text="Test Button text-overflow: initial, this should be long sentence and truncated in the middle with ellipsis." textOverflow="initial" whiteSpace="nowrap" />
27+
</GridLayout>
1728
<Label text="maxLines 2" fontWeight="bold" marginTop="10" />
1829
<Label
1930
text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

packages/core/core-types/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ export namespace CoreTypes {
9494
export const nowrap = 'nowrap';
9595
}
9696

97+
export type TextOverflowType = 'clip' | 'ellipsis' | 'initial' | 'unset';
98+
export namespace TextOverflow {
99+
export const clip = 'clip';
100+
export const ellipsis = 'ellipsis';
101+
export const initial = 'initial';
102+
export const unset = 'unset';
103+
}
104+
97105
export type MaxLinesType = number;
98106

99107
export type OrientationType = 'horizontal' | 'vertical';

packages/core/ui/button/index.ios.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ControlStateChangeListener } from '../core/control-state-change';
22
import { ButtonBase } from './button-common';
33
import { View, PseudoClassHandler } from '../core/view';
44
import { backgroundColorProperty, borderTopWidthProperty, borderRightWidthProperty, borderBottomWidthProperty, borderLeftWidthProperty, paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty } from '../styling/style-properties';
5-
import { textAlignmentProperty, whiteSpaceProperty } from '../text-base';
5+
import { textAlignmentProperty, whiteSpaceProperty, textOverflowProperty } from '../text-base';
66
import { layout } from '../../utils';
77
import { CoreTypes } from '../../core-types';
88
import { Color } from '../../color';
@@ -219,17 +219,42 @@ export class Button extends ButtonBase {
219219
}
220220

221221
[whiteSpaceProperty.setNative](value: CoreTypes.WhiteSpaceType) {
222+
this.adjustLineBreak();
223+
}
224+
225+
[textOverflowProperty.setNative](value: CoreTypes.TextOverflowType) {
226+
this.adjustLineBreak();
227+
}
228+
229+
private adjustLineBreak() {
230+
const whiteSpace = this.whiteSpace;
231+
const textOverflow = this.textOverflow;
222232
const nativeView = this.nativeViewProtected.titleLabel;
223-
switch (value) {
233+
switch (whiteSpace) {
224234
case 'normal':
225235
nativeView.lineBreakMode = NSLineBreakMode.ByWordWrapping;
226236
nativeView.numberOfLines = this.maxLines;
227237
break;
228-
case 'nowrap':
229238
case 'initial':
230239
nativeView.lineBreakMode = NSLineBreakMode.ByTruncatingMiddle;
231240
nativeView.numberOfLines = 1;
232241
break;
242+
case 'nowrap':
243+
switch (textOverflow) {
244+
case 'clip':
245+
nativeView.lineBreakMode = NSLineBreakMode.ByClipping;
246+
nativeView.numberOfLines = this.maxLines;
247+
break;
248+
case 'ellipsis':
249+
nativeView.lineBreakMode = NSLineBreakMode.ByTruncatingTail;
250+
nativeView.numberOfLines = 1;
251+
break;
252+
default:
253+
nativeView.lineBreakMode = NSLineBreakMode.ByTruncatingMiddle;
254+
nativeView.numberOfLines = 1;
255+
break;
256+
}
257+
break;
233258
}
234259
}
235260

packages/core/ui/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export { CSSHelper } from './styling/css-selector';
6868

6969
export { Switch } from './switch';
7070
export { TabView, TabViewItem } from './tab-view';
71-
export { TextBase, getTransformedText, letterSpacingProperty, textAlignmentProperty, textDecorationProperty, textTransformProperty, textShadowProperty, whiteSpaceProperty, lineHeightProperty } from './text-base';
71+
export { TextBase, getTransformedText, letterSpacingProperty, textAlignmentProperty, textDecorationProperty, textTransformProperty, textShadowProperty, whiteSpaceProperty, textOverflowProperty, lineHeightProperty } from './text-base';
7272
export { FormattedString } from './text-base/formatted-string';
7373
export { Span } from './text-base/span';
7474
export { TextField } from './text-field';

packages/core/ui/label/index.ios.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Length, borderTopWidthProperty, borderRightWidthProperty, borderBottomW
44
import { booleanConverter } from '../core/view-base';
55
import { View, CSSType } from '../core/view';
66
import { CoreTypes } from '../../core-types';
7-
import { TextBase, whiteSpaceProperty } from '../text-base';
7+
import { TextBase, whiteSpaceProperty, textOverflowProperty } from '../text-base';
88
import { layout } from '../../utils';
99

1010
import { ios } from '../styling/background';
@@ -113,17 +113,38 @@ export class Label extends TextBase implements LabelDefinition {
113113
}
114114

115115
[whiteSpaceProperty.setNative](value: CoreTypes.WhiteSpaceType) {
116-
const nativeView = this.nativeTextViewProtected;
117-
switch (value) {
116+
this.adjustLineBreak();
117+
}
118+
119+
[textOverflowProperty.setNative](value: CoreTypes.TextOverflowType) {
120+
this.adjustLineBreak();
121+
}
122+
123+
private adjustLineBreak() {
124+
const whiteSpace = this.whiteSpace;
125+
const textOverflow = this.textOverflow;
126+
const nativeView = this.nativeViewProtected;
127+
switch (whiteSpace) {
118128
case 'normal':
119129
nativeView.lineBreakMode = NSLineBreakMode.ByWordWrapping;
120130
nativeView.numberOfLines = this.maxLines;
121131
break;
122-
case 'nowrap':
123132
case 'initial':
124133
nativeView.lineBreakMode = NSLineBreakMode.ByTruncatingTail;
125134
nativeView.numberOfLines = 1;
126135
break;
136+
case 'nowrap':
137+
switch (textOverflow) {
138+
case 'clip':
139+
nativeView.lineBreakMode = NSLineBreakMode.ByClipping;
140+
nativeView.numberOfLines = this.maxLines;
141+
break;
142+
default:
143+
nativeView.lineBreakMode = NSLineBreakMode.ByTruncatingTail;
144+
nativeView.numberOfLines = 1;
145+
break;
146+
}
147+
break;
127148
}
128149
}
129150

packages/core/ui/styling/style/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ export class Style extends Observable implements StyleDefinition {
172172
public textTransform: CoreTypes.TextTransformType;
173173
public textShadow: CSSShadow;
174174
public whiteSpace: CoreTypes.WhiteSpaceType;
175+
public textOverflow: CoreTypes.TextOverflowType;
175176

176177
public minWidth: CoreTypes.LengthType;
177178
public minHeight: CoreTypes.LengthType;

packages/core/ui/text-base/index.android.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Types
2-
import { getClosestPropertyValue, maxLinesProperty } from './text-base-common';
2+
import { getClosestPropertyValue, maxLinesProperty, textOverflowProperty } from './text-base-common';
33
import { CSSShadow } from '../styling/css-shadow';
44

55
// Requires
@@ -311,16 +311,35 @@ export class TextBase extends TextBaseCommon {
311311
// Overridden in TextField because setSingleLine(false) will remove methodTransformation.
312312
// and we don't want to allow TextField to be multiline
313313
[whiteSpaceProperty.setNative](value: CoreTypes.WhiteSpaceType) {
314+
this.adjustLineBreak();
315+
}
316+
317+
[textOverflowProperty.setNative](value: CoreTypes.TextOverflowType) {
318+
this.adjustLineBreak();
319+
}
320+
321+
private adjustLineBreak() {
322+
const whiteSpace = this.whiteSpace;
323+
const textOverflow = this.textOverflow;
314324
const nativeView = this.nativeTextViewProtected;
315-
switch (value) {
325+
switch (whiteSpace) {
316326
case 'initial':
317327
case 'normal':
318328
nativeView.setSingleLine(false);
319329
nativeView.setEllipsize(null);
320330
break;
321331
case 'nowrap':
322-
nativeView.setSingleLine(true);
323-
nativeView.setEllipsize(android.text.TextUtils.TruncateAt.END);
332+
switch (textOverflow) {
333+
case 'initial':
334+
case 'ellipsis':
335+
nativeView.setSingleLine(true);
336+
nativeView.setEllipsize(android.text.TextUtils.TruncateAt.END);
337+
break;
338+
default:
339+
nativeView.setSingleLine(false);
340+
nativeView.setEllipsize(android.text.TextUtils.TruncateAt.END);
341+
break;
342+
}
324343
break;
325344
}
326345
}

packages/core/ui/text-base/index.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ export class TextBase extends View implements AddChildFromBuilder {
6363
*/
6464
whiteSpace: CoreTypes.WhiteSpaceType;
6565

66+
/**
67+
* Gets or sets text-overflow style property.
68+
*/
69+
textOverflow: CoreTypes.TextOverflowType;
70+
6671
/**
6772
* Gets or sets white space style property.
6873
*/
@@ -134,6 +139,7 @@ export const textDecorationProperty: CssProperty<Style, CoreTypes.TextDecoration
134139
export const textTransformProperty: CssProperty<Style, CoreTypes.TextTransformType>;
135140
export const textShadowProperty: CssProperty<Style, CSSShadow>;
136141
export const whiteSpaceProperty: CssProperty<Style, CoreTypes.WhiteSpaceType>;
142+
export const textOverflowProperty: CssProperty<Style, CoreTypes.TextOverflowType>;
137143
export const letterSpacingProperty: CssProperty<Style, number>;
138144
export const lineHeightProperty: CssProperty<Style, number>;
139145

packages/core/ui/text-base/text-base-common.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ export abstract class TextBaseCommon extends View implements TextBaseDefinition
132132
this.style.whiteSpace = value;
133133
}
134134

135+
get textOverflow(): CoreTypes.TextOverflowType {
136+
return this.style.textOverflow;
137+
}
138+
set textOverflow(value: CoreTypes.TextOverflowType) {
139+
this.style.textOverflow = value;
140+
}
141+
135142
get padding(): string | CoreTypes.LengthType {
136143
return this.style.padding;
137144
}
@@ -291,6 +298,16 @@ export const whiteSpaceProperty = new CssProperty<Style, CoreTypes.WhiteSpaceTyp
291298
});
292299
whiteSpaceProperty.register(Style);
293300

301+
const textOverflowConverter = makeParser<CoreTypes.TextOverflowType>(makeValidator<CoreTypes.TextOverflowType>('clip', 'ellipsis', 'initial', 'unset'));
302+
export const textOverflowProperty = new CssProperty<Style, CoreTypes.TextOverflowType>({
303+
name: 'textOverflow',
304+
cssName: 'text-overflow',
305+
defaultValue: 'initial',
306+
affectsLayout: global.isIOS,
307+
valueConverter: textOverflowConverter,
308+
});
309+
textOverflowProperty.register(Style);
310+
294311
const textDecorationConverter = makeParser<CoreTypes.TextDecorationType>(makeValidator<CoreTypes.TextDecorationType>('none', 'underline', 'line-through', 'underline line-through'));
295312
export const textDecorationProperty = new CssProperty<Style, CoreTypes.TextDecorationType>({
296313
name: 'textDecoration',

0 commit comments

Comments
 (0)