Skip to content

Commit 594327f

Browse files
committed
feat(coercion): add utility for coercing CSS values
Moves some duplicated logic for coercing CSS values under `cdk/coercion` and replaces the usages.
1 parent 7857b92 commit 594327f

File tree

6 files changed

+57
-27
lines changed

6 files changed

+57
-27
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import {coerceCssPixelValue} from './css-pixel-value';
2+
3+
describe('coerceCssPixelValue', () => {
4+
it('should add pixel units to a number value', () => {
5+
expect(coerceCssPixelValue(1337)).toBe('1337px');
6+
});
7+
8+
it('should ignore string values', () => {
9+
expect(coerceCssPixelValue('1337rem')).toBe('1337rem');
10+
});
11+
12+
it('should return an empty string for null', () => {
13+
expect(coerceCssPixelValue(null)).toBe('');
14+
});
15+
16+
it('should return an empty string for undefined', () => {
17+
expect(coerceCssPixelValue(undefined)).toBe('');
18+
});
19+
});

src/cdk/coercion/css-pixel-value.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
/** Coerces a value to a CSS pixel value. */
10+
export function coerceCssPixelValue(value: any): string {
11+
if (value == null) {
12+
return '';
13+
}
14+
15+
return typeof value === 'string' ? value : `${value}px`;
16+
}

src/cdk/coercion/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
export * from './boolean-property';
1010
export * from './number-property';
1111
export * from './array';
12+
export * from './css-pixel-value';

src/cdk/overlay/overlay-ref.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {Observable, Subject} from 'rxjs';
1313
import {take} from 'rxjs/operators';
1414
import {OverlayKeyboardDispatcher} from './keyboard/overlay-keyboard-dispatcher';
1515
import {OverlayConfig} from './overlay-config';
16+
import {coerceCssPixelValue} from '@angular/cdk/coercion';
1617

1718

1819
/** An object where all of its properties cannot be written. */
@@ -254,27 +255,27 @@ export class OverlayRef implements PortalOutlet {
254255
/** Updates the size of the overlay element based on the overlay config. */
255256
private _updateElementSize() {
256257
if (this._config.width || this._config.width === 0) {
257-
this._pane.style.width = formatCssUnit(this._config.width);
258+
this._pane.style.width = coerceCssPixelValue(this._config.width);
258259
}
259260

260261
if (this._config.height || this._config.height === 0) {
261-
this._pane.style.height = formatCssUnit(this._config.height);
262+
this._pane.style.height = coerceCssPixelValue(this._config.height);
262263
}
263264

264265
if (this._config.minWidth || this._config.minWidth === 0) {
265-
this._pane.style.minWidth = formatCssUnit(this._config.minWidth);
266+
this._pane.style.minWidth = coerceCssPixelValue(this._config.minWidth);
266267
}
267268

268269
if (this._config.minHeight || this._config.minHeight === 0) {
269-
this._pane.style.minHeight = formatCssUnit(this._config.minHeight);
270+
this._pane.style.minHeight = coerceCssPixelValue(this._config.minHeight);
270271
}
271272

272273
if (this._config.maxWidth || this._config.maxWidth === 0) {
273-
this._pane.style.maxWidth = formatCssUnit(this._config.maxWidth);
274+
this._pane.style.maxWidth = coerceCssPixelValue(this._config.maxWidth);
274275
}
275276

276277
if (this._config.maxHeight || this._config.maxHeight === 0) {
277-
this._pane.style.maxHeight = formatCssUnit(this._config.maxHeight);
278+
this._pane.style.maxHeight = coerceCssPixelValue(this._config.maxHeight);
278279
}
279280
}
280281

@@ -369,10 +370,6 @@ export class OverlayRef implements PortalOutlet {
369370
}
370371
}
371372

372-
function formatCssUnit(value: number | string) {
373-
return typeof value === 'string' ? value as string : `${value}px`;
374-
}
375-
376373

377374
/** Size properties for an overlay. */
378375
export interface OverlaySizeConfig {

src/cdk/overlay/position/flexible-connected-position-strategy.ts

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
import {Observable, Subscription, Subject} from 'rxjs';
1818
import {OverlayRef} from '../overlay-ref';
1919
import {isElementScrolledOutsideView, isElementClippedByScrolling} from './scroll-clip';
20+
import {coerceCssPixelValue} from '@angular/cdk/coercion';
2021

2122

2223
// TODO: refactor clipping detection into a separate thing (part of scrolling module)
@@ -665,29 +666,29 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
665666
styles.bottom = '';
666667
styles.height = '100%';
667668
} else {
668-
styles.height = `${boundingBoxRect.height}px`;
669-
styles.top = boundingBoxRect.top != null ? `${boundingBoxRect.top}px` : '';
670-
styles.bottom = boundingBoxRect.bottom != null ? `${boundingBoxRect.bottom}px` : '';
669+
styles.top = coerceCssPixelValue(boundingBoxRect.top);
670+
styles.bottom = coerceCssPixelValue(boundingBoxRect.bottom);
671+
styles.height = coerceCssPixelValue(boundingBoxRect.height);
671672
}
672673

673674
if (!this._hasFlexibleWidth || this._isPushed) {
674675
styles.left = '0';
675676
styles.right = '';
676677
styles.width = '100%';
677678
} else {
678-
styles.width = `${boundingBoxRect.width}px`;
679-
styles.left = boundingBoxRect.left != null ? `${boundingBoxRect.left}px` : '';
680-
styles.right = boundingBoxRect.right != null ? `${boundingBoxRect.right}px` : '';
679+
styles.left = coerceCssPixelValue(boundingBoxRect.left);
680+
styles.right = coerceCssPixelValue(boundingBoxRect.right);
681+
styles.width = coerceCssPixelValue(boundingBoxRect.width);
681682
}
682683

683684
const maxHeight = this._overlayRef.getConfig().maxHeight;
684685
if (maxHeight && this._hasFlexibleHeight) {
685-
styles.maxHeight = formatCssUnit(maxHeight);
686+
styles.maxHeight = coerceCssPixelValue(maxHeight);
686687
}
687688

688689
const maxWidth = this._overlayRef.getConfig().maxWidth;
689690
if (maxWidth && this._hasFlexibleWidth) {
690-
styles.maxWidth = formatCssUnit(maxWidth);
691+
styles.maxWidth = coerceCssPixelValue(maxWidth);
691692
}
692693

693694
this._lastBoundingBoxSize = boundingBoxRect;
@@ -800,7 +801,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
800801
const documentHeight = this._document.documentElement.clientHeight;
801802
styles.bottom = `${documentHeight - (overlayPoint.y + this._overlayRect.height)}px`;
802803
} else {
803-
styles.top = `${overlayPoint.y}px`;
804+
styles.top = coerceCssPixelValue(overlayPoint.y);
804805
}
805806

806807
return styles;
@@ -835,7 +836,7 @@ export class FlexibleConnectedPositionStrategy implements PositionStrategy {
835836
const documentWidth = this._document.documentElement.clientWidth;
836837
styles.right = `${documentWidth - (overlayPoint.x + this._overlayRect.width)}px`;
837838
} else {
838-
styles.left = `${overlayPoint.x}px`;
839+
styles.left = coerceCssPixelValue(overlayPoint.x);
839840
}
840841

841842
return styles;
@@ -971,11 +972,6 @@ export interface ConnectedPosition {
971972
offsetY?: number;
972973
}
973974

974-
// TODO: move to common place
975-
function formatCssUnit(value: number | string) {
976-
return typeof value === 'string' ? value as string : `${value}px`;
977-
}
978-
979975
/** Shallow-extends a stylesheet object with another stylesheet object. */
980976
function extendStyles(dest: CSSStyleDeclaration, source: CSSStyleDeclaration): CSSStyleDeclaration {
981977
for (let key in source) {

src/cdk/overlay/scroll/block-scroll-strategy.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import {ScrollStrategy} from './scroll-strategy';
1010
import {ViewportRuler} from '@angular/cdk/scrolling';
11+
import {coerceCssPixelValue} from '@angular/cdk/coercion';
1112

1213
/**
1314
* Strategy that will prevent the user from scrolling while the overlay is visible.
@@ -38,8 +39,8 @@ export class BlockScrollStrategy implements ScrollStrategy {
3839

3940
// Note: we're using the `html` node, instead of the `body`, because the `body` may
4041
// have the user agent margin, whereas the `html` is guaranteed not to have one.
41-
root.style.left = `${-this._previousScrollPosition.left}px`;
42-
root.style.top = `${-this._previousScrollPosition.top}px`;
42+
root.style.left = coerceCssPixelValue(-this._previousScrollPosition.left);
43+
root.style.top = coerceCssPixelValue(-this._previousScrollPosition.top);
4344
root.classList.add('cdk-global-scrollblock');
4445
this._isEnabled = true;
4546
}

0 commit comments

Comments
 (0)