This fixes a bug in the negotiation logic that caused a cycle of
terminate->grant events to be sent to the current responder during a pointer
move. The root cause was using an incorrect event path in the calculation of
the lowest common ancestor's index. The fix is to ensure that the event path
stored with the current responder is pruned to begin with the node that is the
current responder (rather than any child responders it may have contained).
If a pan interaction has taken place, it is not expected that 'click' events
occur on the target element when the pointer is released (as was occuring with
mouse pointers). This patch cancels any 'click' that occurs within the pan
target's subtree, within 250ms of the pan gesture ending.
Fix#1788
If a pressable is disabled it should not prevent the propagation of native
'click' events, unless the underlying DOM node has an 'aria-role' of 'button'.
This emulates the native '<button>' behavior.
Fix#1781
This is an Android-only prop that has no platform guard in React Native. The
web has a native 'collapsable' prop that React DOM complains about when it is
not a string value.
Close#1767
This patch ports the 'useHover' hook to React Native for Web, providing hover
state that is scoped to a pressable and does not bubble to ancestor pressables.
This behavior aligns with the behavior of the focus and press states.
Fix#1708
This adds support for the React Native Modal on web.
The app content is hidden from screen readers by setting the aria-modal flag on
the modal. This focus is trapped within the modal, both when attempting to
focus elsewhere using the mouse as well as when attempting to focus elsewhere
using the keyboard. A built-in "Escape to close" mechanism is been implemented
that calls 'onRequestClose' for the active modal.
Close#1646Fix#1020
React Native has an implementation of flexbox that does not quite follow the
W3C spec for flexbox. Previously, React Native for Web attempted to replicate
the React Native rendering by setting flexBasis to 0%. However, this created
its own problems where views could collapse down to 0px in height on the web.
This patch relies sets the default flexBasis back to 'auto'. This will cause
different rendering inconsistencies with React Native, which can be addressed
by making changes to existing React Native styles. And ultimately, it is up to
Yoga to correct its flexbox implementation.
Fix#1640Fix#1604Fix#1264Close#1265
Ensure internal refs are called before the forwardedRef. This ensures that the
DOM element mutation performed by usePlatformMethods occurs before user-space
refs are called.
Ref #1749
The previous code wasn't inserting the W3C rule because it had the same selector as the rule for proprietary styles. However, the Firefox value isn't supported anymore, and the Edge value is unnecessary as Edge uses Blink now. This patch removes the non-WebKit fallback styles for this property.
Fix#1760
This patch fixes the PressResponder to avoid propagating click and contextmenu
events in all circumstances. It also prevents click propagating for focusable
elements that are disabled, mirroring the behavior of native buttons when
disabled.
Fix#1757
React doesn't currently provide an API for defining SSR-safe IDs, so we have to
suppress the hydration warnings that occur.
The 'useOpaqueIdentifier' hook is intended to support this use case but is not
currently a public API and development has been paused.
https://github.com/facebook/react/pull/17322.
Close#1375
Move the touch identifier normalization into the ResponderEvent creation. This ensures that the identifier is consistent throughout. If application code reads an identifier from a touch object it can be used to find that touch in the `touchBank` array.
Fix#1716
Don't rely on native restrictions and validations for these keyboardType
values, as developers often want custom presentation (e.g., comma separators)
and custom validation.
Fix#1705Fix#1438Fix#1280Close#1709
If 'onLayout' is an inline function, it could cause the DOM node to enter a
cycle of being observed/unobserved with the result that 'onLayout' was
constantly called.
Fix#1704
There should be responder negotiation between siblings if there is no common ancestor connected to the responder system. Instead the current responder should continue to receive events. This was only occuring for mouse events during mousemove, as the target can change during the course of the movement.
Remove the 'accessibilityRelationship' prop which is not part of React Native.
The general approach to supporting ARIA-like accessibility APIs in React Native
needs revisiting and it will be easier to stop going down this path.
This patch also reverts the "unstable_ariaSet" change, and renames
"unstable_dataSet" to "dataSet". Avoiding another breaking change to
accessibility props will ease upgrading for now.
If keyup events fall through to a "pressable" element that is not the responder
(e.g., a keydown in a modal closes the modal) it should not attempt to
transition the state.
Also replace invariant with console.error to allow the app to recover if
unexpected signals occur.
Fixes a performance regression in prop forwarding by reintroducing prop filtering.
Fixes ref forwarding to host components, mutating the host node to add imperative APIs.
Port and rewrite "Pressability" from React Native as "PressResponder". This
integrates a press target with the responder system on web. It avoids
performing layout measurement during gestures by eschewing React Native's
iOS-like UX in favor of expected Web UX: a press target will look pressed until
the pointer is released, even if the pointer has moved outside the bounding
rect of the target.
The PressResponder is used to reimplement the existing Touchables. It's
expected that they will eventually be removed in favor of Pressable.
Fix#1583Fix#1564Fix#1534Fix#1419Fix#1219Fix#1166
Makes `onClick` part of the stable props API. In the future this will be used
to implement `onPress` in the Touchables/Pressables. Special handling of click
for keyboards is performed in `createElement`. At the moment, `Text` still
includes the `onPress` prop, which will only be called if `onClick` is not also
being used. In the future `Text` (in React Native) should remove the Touchable
props from its API.
Replaces the ResponderEventPlugin with useResponderEvents hook.
Also removes the event "normalization" of mouse, touch, and click events.
These events are not part of the responder system and will no longer be
modified from what ReactDOM dispatches.
Fix#1589Fix#1568Fix#1571Fix#829Fix#693
This is copied from facebook/react with various fixes applied (which I'll push
upstream at a later date). Necessary for testing the Responder Event System
rewrite.
Rather than filtering props, they are explicitly forwarded in each component.
This makes it easier to see exactly which props are being forwarded to host
components by each React Native component. Two new props - `unstable_ariaSet`
and `unstable_dataSet` - are introduced to avoid iterating over props to find
`aria` and `data` props.
The `accessibilityValue` prop is also implemented.
Rewrite View to use function components and hooks.
The 'usePlatformMethods' hook also fixes a bug in the class-based
implementation of 'setNativeProps' which was unable to correctly merge its
styles with those provided via the component API. In the future,
'setNativeProps' will be removed from React Native anyway.
See (3) in #1136 for more context.
A hook equivalent for implementing onLayout in function components. Removes
the fallback to using window resize events. A ResizeObserver polyfill is now
requires to use the `onLayout` prop.
Renders the asset scale which is closest to the window scale. Requires bundler integration.
Close#1456
Co-authored-by: David Calhoun <dpcalhoun@gmail.com>
Jest dumps the invariant error to the console when unit tests run, which is
both annoying and more likely to cause unwanted error to go unnoticed. We're
also moving away from using 'invariant' in React. This patch replaces the
invariant with a call to 'console.error', which won't crash an app that is
using raw text nodes as View children, but it's better than nothing.
Fix 'autoComplete' behavior now that Chrome has fixed broken behavior for 'off'.
Add fallback support for React Native's 'autoCompleteType' prop.
Close#1404
Remove support for legacy React Native props and add support for the
'trackColor' object. Retains support for the web-only equivalents as I think
this API is preferable to the one in React Native, both in terms of flexibility
and performance (no inline objects).
Fix#1382
Removes the following deprecated exports: `ColorPropType`,
`EdgeInsetsPropType`, `PointPropType`, `TextPropTypes`, and `ViewPropTypes`.
Remove all use of `prop-types` in the implementations of components. Flow types
are used instead, so there will no longer be runtime warnings related to props.
NOTE: Removes support for `className` prop.
Fix#1383Close#1477Close#1474Close#1489
Client-side hydration of server-rendered HTML now requires that `hydrate` is explicitly set in the `appParams` passed to `AppRegistry.runApplication()`.
Fix#1374
Adds the accessibilityState and accessibilityRelationship object props that map
to ARIA props.
Removes the accessibilityStates array prop that is not compatible with web
accessibility services.
Ref #1172
Close#1355
InteractionManager runAfterInteractions does not resolve its promise unless the function is provided with a callback. Using promises, the user of the library should not need to provide a callback. This update adds an else case when there is no callback to call the Promise's resolve function without arguments.
Implements 'showsHorizontalScrollIndicator' and 'showVerticalScrollIndicator' by polyfilling the 'scrollbar-width' property from the draft CSS spec for scrollbars. Scrollbars can only be shown for both or neither axis.
Close#1307
Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
Attempting to fallback to CSS2 text-decoration is not reliable for inline
styles. This patch assumes CSS3 text-decoration support when server-rendering,
and uses CSS.supports to check for runtime support. When CSS3 support is
available the long-form properties are preserved.
Fix#1312
This fixes an issue that would cause the defaultSource to be removed as soon as
the source beings to load. The original intent was to support progressive
JPEGs. However, in cases where a defaultSource has been provided, we should
respect the intent to display it until the primary source is ready to
immediately replace the defaultSource.
Close#1345
Image.queryCache is a React Native method that allows the user to see
if a given uri is in the cache. It specifies three return options:
disk, memory or both. Choosing both seemed most appropriate since
we don't really know and can't confirm.
The way Image is implemented, if RNW thinks the image might already
be loaded, it displays it immediately. Otherwise there can be a flash
of a frame. In some scenarios, if the user chooses to preload and then
make an Image element, it would still flash. By adding it to the cache,
we can prevent that.
Close#1344
Recently the default export was removed from react-native-web. In some
scenarios it is possible to still get to this import path which does not work
anymore. Removing the `.default` fixes commonjs imports from index.
Close#1341
Edge browser throws `HierarchyRequestError` while inserting CSS rules into CSS
Media Queries. Therefore, a different mechanism is required to control CSS
order. This patch tracks the starting index of each group of CSS rules in the
DOM style sheet.
Fix#1300Close#1302
Hack something together to get classic CSS going through the same pathway as
the rest of the styles. This gets classic CSS showing up in the SSR CSS output.
Fix#1286
Rather than mix shortform and longform properties, the 'outline' property is
removed in favour of the longform properties. Support for `outlineOffset` is
also included.
Fix#1255Close#1256
The CSS base styles for certain primitives are implemented using classic CSS to
reduce browser layout times and better support 'null' values in
StyleSheet-defined styles. Combined with the previous patch this reduces the
benchmark layout times by about 30%.
Ref #1136Fix#1044Fix#1223Fix#13
Introduces a centralized compiler for "atomic" and "classic" CSS output. The
"classic" compiler is for internal use only and offers no CSS safety
guarantees. The "atomic compiler is used to implement the public-facing
StyleSheet API.
The atomic compiler now maps the React style declarations, rather than CSS
style declarations, to CSS rules. This avoids having to convert React styles to
CSS styles before being able to lookup classNames. And it reduces the number of
CSS rules needed by each DOM element.
Before:
{ paddingHorizontal: 0; }
↓
.paddingLeft-0 { padding-left: 0; }
.paddingRight-0 { padding-right: 0; }
After:
{ paddingHorizontal: 0; }
↓
.paddingHorizontal-0 { padding-left: 0; padding-right: 0 }
Overview of previous StyleSheet resolver:
1. Localise styles
2. Transform to CSS styles
3. Expand short-form properties
4a. Lookup Atomic CSS for each declaration
4b. Compile Atomic CSS for each static declaration
i. Vendor prefix
ii. Insert CSS rules
4c. Create inline style for each dynamic-only declaration
i. Vendor prefix
Overview of new StyleSheet design:
1. Localise styles
2a. Lookup Atomic CSS for each declaration
2b. Compile Atomic CSS for each static declarations
i. Transform to CSS styles
ii. Expand short-form properties
iii. Vendor prefix
iiii. Insert CSS rules
2c. Create inline style for each dynamic-only declaration
i. Transform to CSS styles
ii. Expand short-form properties
iii. Vendor prefix
Ref #1136
`OrderedCSSStyleSheet` can be used to control the order in which CSS rules are
inserted. This feature is necessary to support the combined use of Classic CSS
and Atomic CSS. It also makes it possible to control the order of Atomic CSS
rules, which is necessary to correctly resolve style conflicts (e.g., between
'margin' and 'marginHorizontal') without expanding short-form properties to
long-form properties.
Ref #1136
Creates a {path}/index.js for each module that has no web
implementation. This enables the babel preset to rewrite all paths and
prevent apps from bundling unused modules.
Fix#1281Close#1282
Remove the default export that was provided for compatibility with legacy
imports of React Native CommonJS modules. These patterns are no longer
supported:
```
import ReactNative from 'react-native';
const ReactNative = require('react-native');
```
Fix#1258Close#1277
Browsers treat autoComplete "off" as "on". The fix is to provide the browser
with an unrecognized value so that it doesn't attempt to auto-fill the input.
Fix#1249
React Native 0.57 introduced 'accessibilityRole' and
'accessibilityStates' as cross-platform accessibility APIs to replace
'accessibilityComponentType' and 'accessibilityTraits' for Android and
iOS.
React Native for Web has supported the 'accessibilityRole' for a while.
This patch maps some of the values defined in React Native to web
equivalents, and continues to allow a larger selection of roles for web
apps. It also adds support for 'accessibilityStates', mapping values to
ARIA states with boolean values and expanding support beyond 'disabled'
and 'selected'.
Fix#1112Close#1113
Inserting unprefixed CSS keyframes rules causes a `SYNTAX_ERR: DOM Exception
12` error in Android 5.1. A similar issue with inserting rules containing
vendor-prefixed pseudo-selectors was patched by wrapping rule in `@media all
{}` blocks. This patch removes the media query wrapper from keyframe animations
(as it doesn't prevent the error) and relies on `CSSStyleSheet::insertRule`
being called within a try-catch block.
Fix#1199Close#1210
Script time in the benchmark was profiled by adding `console.profile` around
the timings for script time. The call to Array.join in the resolve function
stood out. Since the code already iterates over the array it can run slightly
faster by building the cache key in that loop instead.
Close#1213
Not every item that may be rendered by a ScrollView will forward 'style', so cloning the item element is not safe. Instead, we can wrap the item in a 'View' and apply the styles for the sticky header to this element.
Close#1175
Inserting and deleting the CSS ':focus' rule triggers styles recalculation for the
entire DOM tree which results in performance degradation on focus and makes the
keyboard very slow to open in Safari iOS.
This commit fixes the issue by picking up the upstream changes to the W3C
focus-visible polyfill. A class name is applied to elements when they receive
focus via keyboard. The related CSS rule is inserted only once into the style
sheet. This performs much better since the browser needs to recalculate styles
only for the focused element and its small subtree.
Fix#1155Close#1169
Ensure that programmatic focus can be moved to any element. Each
instance of a primitive component type (e.g., `View`, `Text`, etc.)
includes a `focus` method. However, on the web only certain elements can
receive programmatic focus by default: those that can also receive
keyboard focus, e.g., `a`, `button`, `input`, etc. All other element
types must set `tabIndex="-1"` in order to be programmatically focusable
without also being focusable via keyboard or mouse.
Fix#1099
Calculating the `location{X,Y}` values for events requires a call to
`getBoundingClientRect`. To prevent unnecessary performance costs, these values
are implemented as getters and will only make the DOM API call when accessed in
application code.
Close#1157
Use of 'pan-x' and 'pan-y' on ScrollView prevents the browser handling
scrolling of a parent ScrollView that is scrollable along the other axis.
Fix#1160Close#1161
Maps the View and Text prop 'nativeID' to DOM 'id' as these are
equivalent. Enables declarative use of various 'aria-*' properties that
require ID references.
Ref #1116Close#1130
The way that sticky headers work on web requires the ScrollView to apply
'position:sticky' to a clone of the element. This wasn't working for
VirtualizedList because the style prop was not passed to the default
CellRendererComponent implementation.
Fix#1066Close#1122
Only observe nodes when the 'onLayout' prop is specified on the
element. Fixes performance regression for browsers that rely on
MutationObserver-based shim for ResizeObserver.
Fix#1128Close#1129
If the work related to a touch/press event takes a long enough time
(i.e., CPU intensive, old device, etc.) the browser may produce emulated
mouse events >500ms after the original touch event. This causes the
related Responder events to fire twice. To avoid that happening, this
patch increases the filter threshold used by the ResponderEventPlugin
from 200ms to 1000ms.
Fix#1078
React DOM 16.5 changed unstable APIs that this project depends upon.
This regression was fixed in React DOM 16.5.1 but requires React Native
for Web to migrate to a different unstable API exported by React DOM.
Fix#1096Close#1106
The 'menuitem' ARIA role should support Enter/Space keyboard interaction
as if it were a button. This is required because the ARIA spec makes it
so that the ARIA properties of 'menuitem' children are ignored, i.e.,
you can't just wrap a button in a 'menuitem' and expect Assistive
Technologies to surface the button to users.
Fix#1068Close#1069
Safari requires '-webkit' prefixes for CSS3 text-decoration styles, and
IE/Edge only support CSS2 text-decoration styles. This patch provides a
fallback for the CSS2 case and relies on the CSS3 properties for color
and style.
Close#1053
Co-authored-by: Nicolas Gallagher <nicolasgallagher@gmail.com>
Fixes an EncodingError exception being thrown in Safari iOS 11 when
decoding an SVG URL. The exception prevents the onLoad handler from
being called.
Close#1063
Comment out React Native's use of non-standard `done()` method, which
isn't available on `async` functions even though it is polyfilled for
the global Promise.
The previous incarnation of this fix would cancel clicks that bubble up
to elements like ScrollViews, with undesired impact on child element
events. Instead, limit the hack to elements with accessibilityRole=link.
Fix#985
Even on high DPI screens, browsers can round sub-pixel values down to
`0`. This causes hairlineWidth borders/heights/etc not to be rendered.
Revert `hairlineWidth` value back to `1`.
Certain HTML elements have a default behaviour (e.g., link navigation)
that can only be prevented in the `click` event handler. The responder
event system doesn't make use of `click` and no callbacks have access to
the `click` event. To prevent unwanted default behaviour, and emulate
the behavior in React Native, the `click` callback will automatically
call `preventDefault()` when the responder system is being used.
The result is that components like `Touchable*` that are overloaded as
web links need to explicitly trigger the link navigation, e.g.,
```
<TouchableOpacity
accessibilityTraits="link"
href={href}
onPress={(e) => {
Linking.openUrl(href);
}}
/>
```
Fix#970
Avoiding unknown property warnings from React DOM. Many components
within and build upon React Native do not filter their own properties
and spread them into View. It is expected that React Native ignore these
properties.
Fix#898
A large number of layout measurements (and their corresponding tasks)
can block the main thread. Make the work async and try to keep the UI
responsive to user input while the layout work is taking place.
Chrome heavily throttles `requestIdleCallback` while scrolling, which
causes delays in image loading. Instead, use the relatively new
`decode()` API to decode the image off the main thread and prevent jank,
without delaying loading itself.
Fix#764
Ref #759
Make sure all the CommonJS modules can be required as normal, rather
than needing to be suffixed with `.default` due to being compiled from
ES modules.
Webpack doesn't like mixing `import` with `module.exports`, and some of
the dynamic requires cannot be safely used in both an ES and CommonJS
module environment without looking for `.default` each time.
React 16.4 includes the necessary ResponderEventPlugin dependencies and
makes some changes to the event internals that causes a breaking change.
This patch fixes rendering with react-dom@16.4 while preserving
backward-compatibility with earlier versions of react-dom.
Close#908
ES modules are the default package export. Commonjs modules are exported
from 'dist/cjs'. Modern bundlers like webpack can consume ES modules.
The addition of the `sideEffects:false` to the `package.json` helps
webpack tree-shaking modules.
Browsers dispatch mouse events after touch events:
https://developer.mozilla.org/en-US/docs/Web/API/Touch_events/Supporting_both_TouchEvent_and_MouseEvent
There have been several attempts to avoid this behaviour affecting the
ResponderEvent system. The previous approach of cancelling the event in
the `onResponderRelease` event handler can end up cancelling other
events that are expected, e.g., `focus`.
Instead, this patch changes the `ResponderEventPlugin.extractEvents`
function to filter the mouse events that occur a short time after a
touch event. (It's assumed that people will not be clicking a mouse
within a few hundred ms of performing a touch.) This allows the
ResponderEvent system to function as expected and leaves other callbacks
to fire as they would be expected to in React DOM, i.e., both
`onTouchStart` and `onMouseDown` will be called following a touch start.
Fix#835Fix#888Fix#932Close#938
Ref #802
Focus-based UIs can use out-of-tree focus algorithms to manage focus
using remote control devices. This patch marks DOM nodes that React
Native considers "focusable".
Close#827
onLayout is called after the component is mounted to the DOM. This makes
both the fallback and ResizeObserver code path behave the same as React
Native.
Fix#911Fix#941Close#939
CSP policy may prevent writing to `<style>` unless a `nonce` attribute
is set. This change makes that possible by moving the modality-related
styles into the main style sheet, and allowing additional props to be
provided to the `<style>` element when rendering on the server. For
example:
```
const { element, getStyleElement } = AppRegistry.getApplication('App');
const html = renderToString(element);
const css = renderToStaticMarkup(getStyleElement({ nonce }));
```
React Native doesn't have `NetInfo.isConnected.getConnectionInfo()`.
This was incorrectly added to the API while updating the main `NetInfo`
API.
Close#937
Reverts #648 as browsers are inconsistent in how they handle
'flex-basis', so this hack isn't effective. And React has no support for
using '!important' in inline styles.
Fix#798
| StatusBar | (✓) | Mock. No equivalent web APIs. |
| Switch | ✓ | |
| Text | ✓ | Missing `onLongPress` ([#1011](https://github.com/necolas/react-native-web/issues/1011)) support. |
| TextInput | ✓ | Missing rich text features ([#1023](https://github.com/necolas/react-native-web/issues/1023)), and auto-expanding behaviour ([#795](https://github.com/necolas/react-native-web/issues/795)). |
| Touchable | ✓ | Includes additional support for mouse and keyboard interactions. |
| TouchableHighlight | ✓ | |
| TouchableNativeFeedback | ✘ | Not started ([#1024](https://github.com/necolas/react-native-web/issues/1024)). |
| TouchableOpacity | ✓ | |
| TouchableWithoutFeedback | ✓ | |
| View | ✓ | |
| VirtualizedList | ✓ | |
| YellowBox | (✓) | Mock. No YellowBox functionality. |
### Modules
| Name | Status | Notes |
| :----------------------- | :----- | :---- |
| AccessibilityInfo | (✓) | Mock. No equivalent web APIs. |
| Alert | ✘ | Not started ([#1026](https://github.com/necolas/react-native-web/issues/1026)). |
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.