diff --git a/packages/react-native-web/src/exports/UIManager/index.js b/packages/react-native-web/src/exports/UIManager/index.js index 64d78132..6d13ab7c 100644 --- a/packages/react-native-web/src/exports/UIManager/index.js +++ b/packages/react-native-web/src/exports/UIManager/index.js @@ -77,7 +77,7 @@ const UIManager = { measureLayout(node, relativeToNativeNode, onSuccess); }, - updateView(node, props, component /* only needed to surpress React errors in development */) { + updateView(node, props) { for (const prop in props) { if (!Object.prototype.hasOwnProperty.call(props, prop)) { continue; @@ -86,7 +86,7 @@ const UIManager = { const value = props[prop]; switch (prop) { case 'style': { - setValueForStyles(node, value, component._reactInternalInstance); + setValueForStyles(node, value); break; } case 'class': diff --git a/packages/react-native-web/src/hooks/usePlatformMethods.js b/packages/react-native-web/src/hooks/usePlatformMethods.js new file mode 100644 index 00000000..d7805dcc --- /dev/null +++ b/packages/react-native-web/src/hooks/usePlatformMethods.js @@ -0,0 +1,75 @@ +/** + * Copyright (c) Nicolas Gallagher. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import type { GenericStyleProp } from '../types'; +import type { ElementRef } from 'react'; + +import UIManager from '../exports/UIManager'; +import createDOMProps from '../modules/createDOMProps'; +import { useImperativeHandle, useRef } from 'react'; + +export default function usePlatformMethods( + hostRef: ElementRef, + ref: ElementRef, + classList: Array, + style: GenericStyleProp +) { + const previousStyle = useRef(null); + + useImperativeHandle( + ref, + () => { + return { + blur() { + UIManager.blur(hostRef.current); + }, + focus() { + UIManager.focus(hostRef.current); + }, + measure(callback) { + UIManager.measure(hostRef.current, callback); + }, + measureLayout(relativeToNativeNode, onFail, onSuccess) { + UIManager.measureLayout(hostRef.current, relativeToNativeNode, onFail, onSuccess); + }, + measureInWindow(callback) { + UIManager.measureInWindow(hostRef.current, callback); + }, + setNativeProps(nativeProps) { + const node = hostRef.current; + if (node && nativeProps) { + const domProps = createDOMProps(null, { + ...nativeProps, + classList: [nativeProps.className, classList], + style: [style, nativeProps.style] + }); + + const nextDomStyle = domProps.style; + + if (previousStyle.current != null) { + if (domProps.style == null) { + domProps.style = {}; + } + for (const styleName in previousStyle.current) { + if (domProps.style[styleName] == null) { + domProps.style[styleName] = ''; + } + } + } + + previousStyle.current = nextDomStyle; + + UIManager.updateView(node, domProps); + } + } + }; + }, + [classList, hostRef, ref, style] + ); +} diff --git a/packages/react-native-web/src/vendor/react-dom/setValueForStyles/index.js b/packages/react-native-web/src/vendor/react-dom/setValueForStyles/index.js index c41e8afe..04abf4fa 100644 --- a/packages/react-native-web/src/vendor/react-dom/setValueForStyles/index.js +++ b/packages/react-native-web/src/vendor/react-dom/setValueForStyles/index.js @@ -12,7 +12,6 @@ import dangerousStyleValue from '../dangerousStyleValue'; import hyphenateStyleName from 'hyphenate-style-name'; -import warnValidStyle from '../warnValidStyle'; /** * Sets the value for multiple styles on a node. If a value is specified as @@ -21,18 +20,13 @@ import warnValidStyle from '../warnValidStyle'; * @param {DOMElement} node * @param {object} styles */ -function setValueForStyles(node, styles, getStack) { +function setValueForStyles(node, styles) { const style = node.style; for (let styleName in styles) { if (!styles.hasOwnProperty(styleName)) { continue; } const isCustomProperty = styleName.indexOf('--') === 0; - if (process.env.NODE_ENV !== 'production') { - if (!isCustomProperty) { - warnValidStyle(styleName, styles[styleName], getStack); - } - } const styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty); if (styleName === 'float') { styleName = 'cssFloat'; diff --git a/scripts/jest/config.js b/scripts/jest/config.js index 7d8a0a35..4c648a54 100644 --- a/scripts/jest/config.js +++ b/scripts/jest/config.js @@ -10,7 +10,7 @@ module.exports = { // resetMocks: true, rootDir: process.cwd(), roots: ['/packages'], - setupFiles: ['jest-canvas-mock'], + setupFiles: ['jest-canvas-mock', require.resolve('./setupFiles.js')], setupFilesAfterEnv: [require.resolve('./setupFramework.js')], snapshotSerializers: ['enzyme-to-json/serializer'], testEnvironment: 'jsdom', diff --git a/scripts/jest/setupFiles.js b/scripts/jest/setupFiles.js new file mode 100644 index 00000000..804c1def --- /dev/null +++ b/scripts/jest/setupFiles.js @@ -0,0 +1,10 @@ +/* eslint-env jasmine, jest */ + +// JSDOM doesn't implement ResizeObserver +class ResizeObserver { + disconnect() {} + observe() {} + unobserve() {} +} + +window.ResizeObserver = ResizeObserver;