From 207edb94f4cc7b59479a40792b92ba5498332662 Mon Sep 17 00:00:00 2001 From: William Tjondrosuharto Date: Sat, 20 Feb 2021 13:39:06 +0700 Subject: [PATCH] chore: box shadow updates (#9220) --- apps/toolbox/src/box-shadow.ts | 5 ---- packages/core/ui/styling/background-common.ts | 18 +++++++++++++ .../core/ui/styling/background.android.ts | 11 +++++--- packages/core/ui/styling/background.d.ts | 3 +++ packages/core/ui/styling/background.ios.ts | 26 ++++++++++++++----- packages/core/ui/styling/style-properties.ts | 3 ++- 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/apps/toolbox/src/box-shadow.ts b/apps/toolbox/src/box-shadow.ts index c45824314..379db6b91 100644 --- a/apps/toolbox/src/box-shadow.ts +++ b/apps/toolbox/src/box-shadow.ts @@ -105,11 +105,6 @@ export class BoxShadowModel extends Observable { } this.appliedBoxShadow = this._boxShadow; this.notifyPropertyChange('appliedBoxShadow', this.appliedBoxShadow); - - // TODO: this is a workaround to apply shadow immediately, - // since the box-shadow logic is currently inside background.ts - this.notifyPropertyChange('background', ''); - this.notifyPropertyChange('background', this.background); } textChange(args): void { diff --git a/packages/core/ui/styling/background-common.ts b/packages/core/ui/styling/background-common.ts index cd49d0c8c..eaf515308 100644 --- a/packages/core/ui/styling/background-common.ts +++ b/packages/core/ui/styling/background-common.ts @@ -4,6 +4,7 @@ import { BackgroundRepeat } from '../styling/style-properties'; import { LinearGradient } from './linear-gradient'; // Types. import { Color } from '../../color'; +import { BoxShadow } from './box-shadow'; export class Background implements BackgroundDefinition { public static default = new Background(); @@ -26,6 +27,7 @@ export class Background implements BackgroundDefinition { public borderBottomLeftRadius = 0; public borderBottomRightRadius = 0; public clipPath: string; + public boxShadow: BoxShadow; private clone(): Background { const clone = new Background(); @@ -48,6 +50,7 @@ export class Background implements BackgroundDefinition { clone.borderBottomRightRadius = this.borderBottomRightRadius; clone.borderBottomLeftRadius = this.borderBottomLeftRadius; clone.clipPath = this.clipPath; + clone.boxShadow = this.boxShadow; return clone; } @@ -178,6 +181,13 @@ export class Background implements BackgroundDefinition { return clone; } + public withBoxShadow(value: BoxShadow): Background { + const clone = this.clone(); + clone.boxShadow = value; + + return clone; + } + public isEmpty(): boolean { return !this.color && !this.image && !this.hasBorderWidth() && !this.hasBorderRadius() && !this.clipPath; } @@ -274,6 +284,14 @@ export class Background implements BackgroundDefinition { return 0; } + public hasBoxShadow(): boolean { + return !!this.boxShadow; + } + + public getBoxShadow(): BoxShadow { + return this.boxShadow; + } + public toString(): string { return `isEmpty: ${this.isEmpty()}; color: ${this.color}; image: ${this.image}; repeat: ${this.repeat}; position: ${this.position}; size: ${this.size}; borderTopColor: ${this.borderTopColor}; borderRightColor: ${this.borderRightColor}; borderBottomColor: ${this.borderBottomColor}; borderLeftColor: ${this.borderLeftColor}; borderTopWidth: ${this.borderTopWidth}; borderRightWidth: ${this.borderRightWidth}; borderBottomWidth: ${this.borderBottomWidth}; borderLeftWidth: ${this.borderLeftWidth}; borderTopLeftRadius: ${this.borderTopLeftRadius}; borderTopRightRadius: ${ this.borderTopRightRadius diff --git a/packages/core/ui/styling/background.android.ts b/packages/core/ui/styling/background.android.ts index 1dcda93bd..5f5974d1e 100644 --- a/packages/core/ui/styling/background.android.ts +++ b/packages/core/ui/styling/background.android.ts @@ -93,9 +93,10 @@ export namespace ad { nativeView.setBackground(defaultDrawable); } - const boxShadow = view.style.boxShadow; - if (boxShadow) { - drawBoxShadow(nativeView, view, boxShadow); + if (background.hasBoxShadow()) { + drawBoxShadow(nativeView, view, background.getBoxShadow()); + } else { + clearBoxShadow(nativeView); } // TODO: Can we move BorderWidths as separate native setter? @@ -243,6 +244,10 @@ function drawBoxShadow(nativeView: android.view.View, view: View, boxShadow: Box org.nativescript.widgets.Utils.drawBoxShadow(nativeView, JSON.stringify(config)); } +function clearBoxShadow(nativeView: android.view.View) { + // org.nativescript.widgets.Utils.clearBoxShadow(nativeView); +} + export enum CacheMode { none, memory, diff --git a/packages/core/ui/styling/background.d.ts b/packages/core/ui/styling/background.d.ts index e8d659247..0d6950768 100644 --- a/packages/core/ui/styling/background.d.ts +++ b/packages/core/ui/styling/background.d.ts @@ -50,6 +50,7 @@ export declare class Background { public withBorderBottomRightRadius(value: number): Background; public withBorderBottomLeftRadius(value: number): Background; public withClipPath(value: string): Background; + public withBoxShadow(value: BoxShadow): Background; public isEmpty(): boolean; @@ -65,6 +66,8 @@ export declare class Background { public getUniformBorderColor(): Color; public getUniformBorderWidth(): number; public getUniformBorderRadius(): number; + public hasBoxShadow(): boolean; + public getBoxShadow(): BoxShadow; } export namespace ios { diff --git a/packages/core/ui/styling/background.ios.ts b/packages/core/ui/styling/background.ios.ts index b035ae656..59e670037 100644 --- a/packages/core/ui/styling/background.ios.ts +++ b/packages/core/ui/styling/background.ios.ts @@ -88,12 +88,11 @@ export namespace ios { setUIColorFromImage(view, nativeView, callback, flip); } - const boxShadow = view.style.boxShadow; - if (boxShadow) { - // this is required (if not, shadow will get cutoff at parent's dimensions) - // nativeView.clipsToBounds doesn't work - view.setProperty('clipToBounds', false); - drawBoxShadow(nativeView, view, boxShadow, background); + if (background.hasBoxShadow()) { + drawBoxShadow(nativeView, view, background.getBoxShadow(), background); + } else { + view.setProperty('clipToBounds', true); + clearBoxShadow(nativeView); } } } @@ -722,6 +721,10 @@ function drawBoxShadow(nativeView: NativeView, view: View, boxShadow: CSSShadow, layer.masksToBounds = false; nativeView.clipsToBounds = false; + + // this is required (if not, shadow will get cutoff at parent's dimensions) + // nativeView.clipsToBounds doesn't work + view.setProperty('clipToBounds', false); if (!background.color?.a) { // add white background if view has a transparent background @@ -745,6 +748,17 @@ function drawBoxShadow(nativeView: NativeView, view: View, boxShadow: CSSShadow, layer.shadowPath = UIBezierPath.bezierPathWithRoundedRectCornerRadius(nativeView.bounds, cornerRadius).CGPath; } +function clearBoxShadow(nativeView: NativeView) { + nativeView.clipsToBounds = true; + const layer: CALayer = nativeView.layer; + layer.masksToBounds = true; + layer.shadowOffset = CGSizeMake(0, 0); + layer.shadowColor = UIColor.clearColor.CGColor; + layer.cornerRadius = 0.0; + layer.shadowRadius = 0.0; + layer.shadowOpacity = 0.0; +} + function drawGradient(nativeView: NativeView, gradient: LinearGradient) { const gradientLayer = CAGradientLayer.layer(); gradientLayer.frame = nativeView.bounds; diff --git a/packages/core/ui/styling/style-properties.ts b/packages/core/ui/styling/style-properties.ts index 49b5e751a..e314f8b57 100644 --- a/packages/core/ui/styling/style-properties.ts +++ b/packages/core/ui/styling/style-properties.ts @@ -1280,7 +1280,8 @@ const boxShadowProperty = new CssProperty({ name: 'boxShadow', cssName: 'box-shadow', valueChanged: (target, oldValue, newValue) => { - target.boxShadow = newValue; + const background = target.backgroundInternal.withBoxShadow(newValue); + target.backgroundInternal = background; }, valueConverter: (value) => { return parseCSSShadow(value);