@nativescript-community/ui-material-core
Version:
Material Core component
408 lines • 17.3 kB
JavaScript
import { Button, Color, ControlStateChangeListener, PercentLength, TouchAction, Utils, View, backgroundInternalProperty } from '@nativescript/core';
import { CornerFamily, applyMixins } from './index.common';
import { cssProperty, dynamicElevationOffsetProperty, elevationProperty, rippleColorAlphaProperty, rippleColorProperty } from './cssproperties';
export * from './cssproperties';
export { applyMixins };
function createCornerFamily(cornerFamily) {
switch (cornerFamily) {
case CornerFamily.CUT:
return 1 /* MDCShapeCornerFamily.Cut */;
default:
case CornerFamily.ROUNDED:
return 0 /* MDCShapeCornerFamily.Rounded */;
}
}
function cornerTreatment(cornerFamily, cornerSize) {
let corner;
if (typeof cornerSize === 'object') {
if (cornerFamily === CornerFamily.CUT) {
if (cornerSize.unit === '%') {
corner = MDCCornerTreatment.cornerWithCutValueType(cornerSize.value, 1);
}
else {
corner = MDCCornerTreatment.cornerWithCutValueType(Utils.layout.toDeviceIndependentPixels(PercentLength.toDevicePixels(cornerSize)), 0);
}
}
else {
if (cornerSize.unit === '%') {
corner = MDCCornerTreatment.cornerWithRadiusValueType(cornerSize.value, 1);
}
else {
corner = MDCCornerTreatment.cornerWithRadiusValueType(Utils.layout.toDeviceIndependentPixels(PercentLength.toDevicePixels(cornerSize)), 0);
}
}
}
else {
if (cornerFamily === CornerFamily.ROUNDED) {
corner = MDCCornerTreatment.cornerWithRadius(Utils.layout.toDeviceIndependentPixels(PercentLength.toDevicePixels(cornerSize)));
}
else {
corner = MDCCornerTreatment.cornerWithCut(Utils.layout.toDeviceIndependentPixels(PercentLength.toDevicePixels(cornerSize)));
}
}
return corner;
}
function getIOSColor(value) {
return (value instanceof Color ? value : new Color(value)).ios;
}
export class Themer {
constructor() {
this._shapes = {};
// create a default one to prevent multiple creations on widget side
this.appColorScheme = MDCSemanticColorScheme.alloc().init().initWithDefaults(2 /* MDCColorSchemeDefaults.Material201907 */);
if (this.appColorScheme.primaryColor) {
this.appColorScheme.primaryColorVariant = this.appColorScheme.primaryColor.colorWithAlphaComponent(0.24);
}
}
getOrcreateAppColorScheme() {
if (!this.appColorScheme) {
this.appColorScheme = MDCSemanticColorScheme.new();
}
return this.appColorScheme;
}
getAppColorScheme() {
return this.appColorScheme;
}
setPrimaryColor(value) {
this.primaryColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
colorTheme.primaryColor = getIOSColor(value);
this.appColorScheme.primaryColorVariant = this.appColorScheme.primaryColor.colorWithAlphaComponent(0.24);
}
getPrimaryColor() {
return this.primaryColor;
}
setOnPrimaryColor(value) {
this.onPrimaryColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
colorTheme.onPrimaryColor = getIOSColor(value);
}
getOnPrimaryColor() {
return this.onPrimaryColor;
}
setSecondaryColor(value) {
this.secondaryColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
colorTheme.secondaryColor = getIOSColor(value);
}
getSecondaryColor() {
return this.secondaryColor;
}
setAccentColor(value) {
this.setSecondaryColor(value);
}
getAccentColor() {
return this.getSecondaryColor();
}
setSurfaceColor(value) {
this.surfaceColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
const color = getIOSColor(value);
colorTheme.surfaceColor = color;
colorTheme.onSurfaceColor = color;
}
getSurfaceColor() {
return this.surfaceColor;
}
setOnSurfaceColor(value) {
this.onSurfaceColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
colorTheme.onSurfaceColor = getIOSColor(value);
}
getOnSurfaceColor() {
return this.onSurfaceColor;
}
setPrimaryColorVariant(value) {
this.primaryColorVariant = value;
this.getOrcreateAppColorScheme().primaryColorVariant = getIOSColor(value);
}
getPrimaryColorVariant() {
return this.primaryColorVariant;
}
setBackgroundColor(value) {
this.backgroundColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
colorTheme.backgroundColor = getIOSColor(value);
}
getBackgroundColor() {
return this.backgroundColor;
}
setOnBackgroundColor(value) {
this.onBackgroundColor = value;
const colorTheme = this.getOrcreateAppColorScheme();
colorTheme.onBackgroundColor = getIOSColor(value);
}
getOnBackgroundColor() {
return this.onBackgroundColor;
}
getOrcreateAppTypographyScheme() {
if (!this.appTypoScheme) {
this.appTypoScheme = MDCTypographyScheme.new();
}
return this.appTypoScheme;
}
getAppTypographyScheme() {
return this.appTypoScheme;
}
setButtonTypography(args) {
// const typoTheme = this.getOrcreateAppTypographyScheme();
// let currentFont = typoTheme.button;
// if (args.fontFamily) {
// currentFont = currentFont.withFontFamily(args.fontFamily);
// }
}
getShape(key) {
return this._shapes[key] || null;
}
createShape(key, options) {
const shapeScheme = MDCShapeScheme.new();
const shapeCategory = MDCShapeCategory.new();
if (options.cornerFamily && options.cornerSize !== undefined) {
const corner = cornerTreatment(options.cornerFamily, options.cornerSize);
shapeCategory.bottomLeftCorner = corner;
shapeCategory.bottomRightCorner = corner;
shapeCategory.topLeftCorner = corner;
shapeCategory.topRightCorner = corner;
}
if (options.cornerSizeBottomLeft !== undefined) {
shapeCategory.bottomLeftCorner = cornerTreatment(options.cornerFamilyBottomLeft || options.cornerFamily, options.cornerSizeBottomLeft);
}
if (options.cornerSizeBottomRight !== undefined) {
shapeCategory.bottomRightCorner = cornerTreatment(options.cornerFamilyBottomRight || options.cornerFamily, options.cornerSizeBottomRight);
}
if (options.cornerSizeTopLeft !== undefined) {
shapeCategory.topLeftCorner = cornerTreatment(options.cornerFamilyTopLeft || options.cornerFamily, options.cornerSizeTopLeft);
}
if (options.cornerSizeTopRight !== undefined) {
shapeCategory.topRightCorner = cornerTreatment(options.cornerFamilyTopRight || options.cornerFamily, options.cornerSizeTopRight);
}
shapeScheme.smallComponentShape = shapeCategory;
shapeScheme.mediumComponentShape = shapeCategory;
shapeScheme.largeComponentShape = shapeCategory;
this._shapes[key] = shapeScheme;
}
}
export const themer = new Themer();
export function install() { }
export function getRippleColor(color, alpha = 61.5) {
if (color) {
const temp = color instanceof Color ? color : new Color(color);
if (temp.a !== 255) {
return temp.ios;
}
// TODO: we cant use setAlpha until it is fixed in Nativescript or ios will be undefined
return new Color(alpha || 61.5, temp.r, temp.g, temp.b).ios;
}
return null;
}
export function overrideViewBase() {
const NSView = require('@nativescript/core').View;
class ViewWithElevationAndRipple extends View {
constructor() {
super(...arguments);
this._shadowElevations = {};
}
getOrCreateRippleController() {
if (!this.inkTouchController) {
// create the shadow Layer
this.inkTouchController = MDCRippleTouchController.alloc().initWithView(this.nativeViewProtected);
// this.inkTouchController.addInkView();
// const colorScheme = themer.getAppColorScheme();
// MDCInkColorThemer.applyColorSchemeToInkView(colorScheme, this.inkTouchController.defaultInkView);
this.inkTouchController.rippleView.usesSuperviewShadowLayerAsMask = true;
// if (this.style.backgroundInternal) {
// this.inkTouchController.rippleView.layer.cornerRadius = Utils.layout.toDeviceIndependentPixels(this.style.backgroundInternal.borderTopLeftRadius);
// }
}
return this.inkTouchController;
}
getOrCreateShadowLayer() {
if (!this.shadowLayer) {
this._shadowElevations = this._shadowElevations || {};
// create the shadow Layer
//@ts-ignore
// const shadowView = ShadowView.alloc().init();
// this.shadowView = shadowView;
// this.shadowView.userInteractionEnabled = false;
// shadowView.clipsToBounds = false;
const layer = (this.shadowLayer = MDCShadowLayer.alloc().init());
// const layer = (this.shadowLayer = shadowView.layer);
layer.shouldRasterize = true;
layer.rasterizationScale = UIScreen.mainScreen.scale;
// shadowView.frame = this.nativeViewProtected.layer.bounds;
layer.frame = this.nativeViewProtected.layer.bounds;
// this.nativeViewProtected.addSubview(shadowView);
this.nativeViewProtected.layer.addSublayer(this.shadowLayer);
// we need to set clipToBounds to false. For now it overrides user choice.
this['clipToBounds'] = false;
this.nativeViewProtected.clipsToBounds = false;
layer.cornerRadius = this.nativeViewProtected.layer.cornerRadius;
layer.mask = this.nativeViewProtected.layer.mask;
// if (this.style.backgroundInternal) {
// layer.cornerRadius = Utils.layout.toDeviceIndependentPixels(this.style.backgroundInternal.borderTopLeftRadius);
// }
if (this.nativeViewProtected instanceof UIControl) {
this.startElevationStateChangeHandler();
}
}
return this.shadowLayer;
}
updateLayers() {
const layer = this.nativeViewProtected?.layer;
if (layer) {
const mask = layer.mask;
if (layer && this.inkTouchController) {
this.inkTouchController.rippleView.layer.cornerRadius = layer.cornerRadius;
this.inkTouchController.rippleView.layer.mask = layer.mask;
}
if (layer && this.shadowLayer) {
this.shadowLayer.frame = this.nativeViewProtected.layer.bounds;
this.shadowLayer.cornerRadius = layer.cornerRadius;
this.shadowLayer.mask = layer.mask;
}
layer.mask = mask;
}
}
_onSizeChanged() {
this.updateLayers();
}
_setNativeClipToBounds() {
if (this.shadowLayer) {
this.nativeViewProtected.clipsToBounds = false;
}
}
onUnloaded() {
if (this._elevationStateChangedHandler) {
if (this._elevationStateChangedHandler.stop) {
this._elevationStateChangedHandler.stop();
}
else {
this.off('touch', this._elevationStateChangedHandler);
}
}
}
updateShadowElevation(state) {
if (this.shadowLayer) {
const elevation = this._shadowElevations[state];
this.shadowLayer.elevation = elevation;
}
}
requestFocus() {
this.focus();
}
clearFocus() {
this.nativeViewProtected.resignFirstResponder();
}
[rippleColorProperty.setNative](color) {
this.getOrCreateRippleController();
this.inkTouchController.rippleView.rippleColor = getRippleColor(color, this.rippleColorAlpha);
}
[rippleColorAlphaProperty.setNative](value) {
const rippleColor = this.rippleColor;
if (rippleColor) {
this[rippleColorProperty.setNative](rippleColor);
}
}
startElevationStateChangeHandler() {
if (!this._elevationStateChangedHandler) {
if (this.nativeViewProtected instanceof UIControl) {
this._elevationStateChangedHandler =
this._elevationStateChangedHandler ||
new ControlStateChangeListener(this.nativeViewProtected, (s) => {
this.updateShadowElevation(s);
});
this._elevationStateChangedHandler.start();
}
else {
this._elevationStateChangedHandler =
this._elevationStateChangedHandler ||
((args) => {
switch (args.action) {
case TouchAction.up:
this.updateShadowElevation('normal');
break;
case TouchAction.down:
this.updateShadowElevation('highlighted');
break;
}
});
this.on('touch', this._elevationStateChangedHandler);
}
}
}
getDefaultElevation() {
return this instanceof Button ? 2 : 0;
}
getDefaultDynamicElevationOffset() {
return this instanceof Button ? 6 : 0;
}
[elevationProperty.getDefault]() {
return this.getDefaultElevation();
}
[elevationProperty.setNative](value) {
this.getOrCreateShadowLayer();
let dynamicElevationOffset = this.dynamicElevationOffset;
if (typeof dynamicElevationOffset === 'undefined' || dynamicElevationOffset === null) {
dynamicElevationOffset = this.getDefaultDynamicElevationOffset();
}
if (dynamicElevationOffset !== 0) {
this.startElevationStateChangeHandler();
}
this._shadowElevations['normal'] = value;
this._shadowElevations['highlighted'] = value + dynamicElevationOffset;
this.shadowLayer.elevation = value;
}
[dynamicElevationOffsetProperty.getDefault]() {
return this.getDefaultDynamicElevationOffset();
}
[dynamicElevationOffsetProperty.setNative](value) {
this.getOrCreateShadowLayer();
this.startElevationStateChangeHandler();
let elevation = this.elevation;
if (typeof elevation === 'undefined' || elevation === null) {
elevation = this.getDefaultElevation();
}
this._shadowElevations['normal'] = elevation;
this._shadowElevations['highlighted'] = value + elevation;
}
[backgroundInternalProperty.setNative](value) {
const layer = this.nativeViewProtected.layer;
if (this.inkTouchController) {
this.inkTouchController.rippleView.layer.cornerRadius = layer.cornerRadius;
this.inkTouchController.rippleView.layer.mask = layer.mask;
}
if (this.shadowLayer) {
this.shadowLayer.cornerRadius = layer.cornerRadius;
this.shadowLayer.mask = layer.mask;
}
}
_redrawNativeBackground(value) {
this.updateLayers();
}
}
__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);
// we need mixins to be applied after (run default implementation first) because of _setNativeClipToBounds.
// it needs to be applied after for shadows to be drawn correctly
applyMixins(NSView, [ViewWithElevationAndRipple], {
after: true
});
}
let mixinInstalled = false;
export function installMixins() {
if (!mixinInstalled) {
mixinInstalled = true;
overrideViewBase();
}
}
//# sourceMappingURL=index.ios.js.map