UNPKG

@nativescript-community/ui-material-core

Version:
350 lines 14.7 kB
import { Button, Color, Length, PercentLength, Utils, View, androidDynamicElevationOffsetProperty, androidElevationProperty, backgroundInternalProperty } from '@nativescript/core'; import { createRippleDrawable, createStateListAnimator, getAttrColor, getColorStateList, handleClearFocus, isPostLollipop, isPostMarshmallow } from './android/utils'; import { cssProperty, dynamicElevationOffsetProperty, elevationProperty, rippleColorAlphaProperty, rippleColorProperty } from './cssproperties'; import { CornerFamily, applyMixins } from './index.common'; export * from './cssproperties'; export { applyMixins }; function cornerTreat(cornerFamily) { switch (cornerFamily) { case CornerFamily.CUT: return new com.google.android.material.shape.CutCornerTreatment(); default: case CornerFamily.ROUNDED: return new com.google.android.material.shape.RoundedCornerTreatment(); } } let context; function getContext() { if (!context) { context = Utils.android.getApplicationContext(); } return context; } // stub class as we don't use this on android export class Themer { constructor() { this._shapes = {}; } // appColorScheme: MDCSemanticColorScheme; getOrcreateAppColorScheme() { // if (!this.appColorScheme) { // this.appColorScheme = MDCSemanticColorScheme.alloc().init(); // } // return this.appColorScheme; } getAppColorScheme() { // return this.appColorScheme; } setPrimaryColor(value) { this.primaryColor = value; } getPrimaryColor() { if (!this.primaryColor) { this.primaryColor = new Color(getAttrColor(getContext(), 'colorPrimary')); } return this.primaryColor; } setOnPrimaryColor(value) { this.onPrimaryColor = value; } getOnPrimaryColor() { if (!this.onPrimaryColor) { this.onPrimaryColor = new Color(getAttrColor(getContext(), 'colorOnPrimary')); } return this.onPrimaryColor; } setAccentColor(value) { this.accentColor = value; } getAccentColor() { if (!this.accentColor) { this.accentColor = new Color(getAttrColor(getContext(), 'colorAccent')); } return this.accentColor; } setSurfaceColor(value) { this.surfaceColor = value; } getSurfaceColor() { return this.surfaceColor; } setOnSurfaceColor(value) { this.onSurfaceColor = value; } getOnSurfaceColor() { return this.onSurfaceColor; } setPrimaryColorVariant(value) { this.primaryColorVariant = value; } getPrimaryColorVariant() { if (!this.primaryColorVariant) { this.primaryColorVariant = new Color(getAttrColor(getContext(), 'colorSecondary')); } return this.primaryColorVariant; } setSecondaryColor(value) { this.secondaryColor = value; } getSecondaryColor() { return this.secondaryColor; } getControlHighlightColor() { if (!this.controlHighlightColor) { this.controlHighlightColor = new Color(getAttrColor(getContext(), 'colorControlHighlight')); } return this.controlHighlightColor; } getShape(key) { return this._shapes[key] || null; } createShape(key, options) { const RelativeCornerSize = com.google.android.material.shape.RelativeCornerSize; const builder = com.google.android.material.shape.ShapeAppearanceModel.builder(); if (options.cornerFamily) { builder.setAllCorners(cornerTreat(options.cornerFamily)); } if (options.cornerFamilyBottomRight) { builder.setBottomRightCorner(cornerTreat(options.cornerFamilyBottomRight)); } if (options.cornerFamilyBottomLeft) { builder.setBottomLeftCorner(cornerTreat(options.cornerFamilyBottomLeft)); } if (options.cornerFamilyTopLeft) { builder.setTopLeftCorner(cornerTreat(options.cornerFamilyTopLeft)); } if (options.cornerFamilyTopRight) { builder.setTopRightCorner(cornerTreat(options.cornerFamilyTopRight)); } if (options.cornerSize !== undefined) { if (typeof options.cornerSize === 'object') { if (options.cornerSize.unit === '%') { builder.setAllCornerSizes(new RelativeCornerSize(options.cornerSize.value)); } else { builder.setAllCornerSizes(PercentLength.toDevicePixels(options.cornerSize)); } } else { builder.setAllCornerSizes(PercentLength.toDevicePixels(options.cornerSize)); } } if (options.cornerSizeBottomLeft !== undefined) { if (typeof options.cornerSizeBottomLeft === 'object') { if (options.cornerSizeBottomLeft.unit === '%') { builder.setBottomLeftCornerSize(new RelativeCornerSize(options.cornerSizeBottomLeft.value)); } else { builder.setBottomLeftCornerSize(PercentLength.toDevicePixels(options.cornerSizeBottomLeft)); } } else { builder.setBottomLeftCornerSize(PercentLength.toDevicePixels(options.cornerSizeBottomLeft)); } } if (options.cornerSizeBottomRight !== undefined) { if (typeof options.cornerSizeBottomRight === 'object') { if (options.cornerSizeBottomRight.unit === '%') { builder.setBottomRightCornerSize(new RelativeCornerSize(options.cornerSizeBottomRight.value)); } else { builder.setBottomRightCornerSize(PercentLength.toDevicePixels(options.cornerSizeBottomRight)); } } else { builder.setBottomRightCornerSize(PercentLength.toDevicePixels(options.cornerSizeBottomRight)); } } if (options.cornerSizeTopRight !== undefined) { if (typeof options.cornerSizeTopRight === 'object') { if (options.cornerSizeTopRight.unit === '%') { builder.setTopRightCornerSize(new RelativeCornerSize(options.cornerSizeTopRight.value)); } else { builder.setTopRightCornerSize(PercentLength.toDevicePixels(options.cornerSizeTopRight)); } } else { builder.setTopRightCornerSize(PercentLength.toDevicePixels(options.cornerSizeTopRight)); } } if (options.cornerSizeTopLeft !== undefined) { if (typeof options.cornerSizeTopLeft === 'object') { if (options.cornerSizeTopLeft.unit === '%') { builder.setTopLeftCornerSize(new RelativeCornerSize(options.cornerSizeTopLeft.value)); } else { builder.setTopLeftCornerSize(PercentLength.toDevicePixels(options.cornerSizeTopLeft)); } } else { builder.setTopLeftCornerSize(PercentLength.toDevicePixels(options.cornerSizeTopLeft)); } } this._shapes[key] = builder.build(); } } export const themer = new Themer(); export function install() { } export function getRippleColor(color, alpha = 0) { if (color) { const temp = color instanceof Color ? color : new Color(color); if (temp.a !== 255 && alpha === 0) { return temp.android; } // TODO: we cant use setAlpha until it is fixed in Nativescript or android will be undefined return new Color(alpha || 61.5, temp.r, temp.g, temp.b).android; // return temp.setAlpha(alpha || 61.5).android; } return null; } let mixinInstalled = false; export function overrideViewBase() { const NSView = require('@nativescript/core').View; class ViewWithElevationAndRipple extends View { constructor() { super(...arguments); this.elevation = 0; this.dynamicElevationOffset = 0; } getRippleColor() { if (this.rippleColor) { return getRippleColor(this.rippleColor); } return getRippleColor(themer.getAccentColor()); } setRippleDrawable(view, topLeftRadius = 0, topRightRadius = 0, bottomRightRadius = 0, bottomLeftRadius = 0) { if (!this.rippleDrawable) { this.rippleDrawable = createRippleDrawable(this.getRippleColor(), topLeftRadius, topRightRadius, bottomRightRadius, bottomLeftRadius); if (isPostMarshmallow) { view.setForeground(this.rippleDrawable); } } } [rippleColorProperty.setNative](color) { const rippleColor = getRippleColor(color, this.rippleColorAlpha); const nativeViewProtected = this.nativeViewProtected; if (this instanceof Button && isPostMarshmallow) { const RippleDrawable = android.graphics.drawable.RippleDrawable; const foreground = nativeViewProtected.getForeground(); if (foreground instanceof RippleDrawable) { foreground.setColor(getColorStateList(rippleColor)); return; } const background = nativeViewProtected.getBackground(); if (background instanceof RippleDrawable) { background.setColor(getColorStateList(rippleColor)); return; } } nativeViewProtected.setClickable(this.isUserInteractionEnabled); const rippleDrawable = this.rippleDrawable; if (!rippleDrawable) { this.setRippleDrawable(nativeViewProtected, Length.toDevicePixels(this.style.borderTopLeftRadius), Length.toDevicePixels(this.style.borderTopRightRadius), Length.toDevicePixels(this.style.borderBottomRightRadius), Length.toDevicePixels(this.style.borderBottomLeftRadius)); } else { if (isPostLollipop) { rippleDrawable.setColor(getColorStateList(rippleColor)); } else if (rippleDrawable.rippleShape) { rippleDrawable.rippleShape.getPaint().setColor(rippleColor); } } } [rippleColorAlphaProperty.setNative](value) { const rippleColor = this.rippleColor; if (rippleColor) { this[rippleColorProperty.setNative](rippleColor); } } [backgroundInternalProperty.setNative](value) { if (this.nativeViewProtected) { if (value instanceof android.graphics.drawable.Drawable) { } else { // we recreate the ripple drawable if necessary. // native button have on the background. Setting color will remove the ripple! if (this.rippleDrawable || (value.color && this instanceof Button && this.rippleColor)) { this.rippleDrawable = null; this.setRippleDrawable(this.nativeViewProtected, Length.toDevicePixels(this.style.borderTopLeftRadius), Length.toDevicePixels(this.style.borderTopRightRadius), Length.toDevicePixels(this.style.borderBottomRightRadius), Length.toDevicePixels(this.style.borderBottomLeftRadius)); } } } } requestFocus() { this.focus(); } clearFocus() { Utils.android.dismissSoftInput(this.nativeViewProtected); handleClearFocus(this.nativeViewProtected); } getDefaultElevation() { const result = this instanceof Button ? 2 : 0; return result; } getDefaultDynamicElevationOffset() { const result = this instanceof Button ? 6 : 0; return result; } [elevationProperty.setNative](value) { if (isPostLollipop) { this.createStateListAnimator(); } else { const newValue = Length.toDevicePixels(typeof value === 'string' ? Length.parse(value) : value, 0); androidx.core.view.ViewCompat.setElevation(this.nativeViewProtected, newValue); } } createStateListAnimator() { if (!this.createStateListAnimatorTimeout) { this.createStateListAnimatorTimeout = setTimeout(() => { this.createStateListAnimatorTimeout = null; if (this.nativeViewProtected) { createStateListAnimator(this, this.nativeViewProtected); } }); } } [dynamicElevationOffsetProperty.setNative](value) { this.nativeViewProtected.setClickable(this.isUserInteractionEnabled); if (isPostLollipop) { this.createStateListAnimator(); } else { const newValue = Length.toDevicePixels(typeof value === 'string' ? Length.parse(value) : value, 0); androidx.core.view.ViewCompat.setTranslationZ(this.nativeViewProtected, newValue); } } } __decorate([ cssProperty ], ViewWithElevationAndRipple.prototype, "elevation", void 0); __decorate([ cssProperty ], ViewWithElevationAndRipple.prototype, "dynamicElevationOffset", void 0); __decorate([ cssProperty ], ViewWithElevationAndRipple.prototype, "rippleColor", void 0); __decorate([ cssProperty ], ViewWithElevationAndRipple.prototype, "rippleColorAlpha", void 0); applyMixins(NSView, [ViewWithElevationAndRipple]); class ViewOverride extends View { [androidElevationProperty.setNative](value) { // override to prevent override of dynamicElevationOffset this[elevationProperty.setNative](value); } [androidDynamicElevationOffsetProperty.setNative](value) { // override to prevent override of elevation this[dynamicElevationOffsetProperty.setNative](value); } } applyMixins(NSView, [ViewOverride], { override: true }); } export function installMixins() { if (!mixinInstalled) { mixinInstalled = true; overrideViewBase(); } } //# sourceMappingURL=index.android.js.map