mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-04-03 22:49:22 +08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
24eda7c4ad | ||
|
|
44ebd8f5a3 | ||
|
|
a3ed8f05e6 | ||
|
|
b653fe0bd3 | ||
|
|
30da226e4d |
@@ -63,6 +63,7 @@ Lets the user select the text.
|
||||
+ ...[View#style](View.md)
|
||||
+ `color`
|
||||
+ `fontFamily`
|
||||
+ `fontFeatureSettings` ‡
|
||||
+ `fontSize`
|
||||
+ `fontStyle`
|
||||
+ `fontWeight`
|
||||
@@ -71,17 +72,19 @@ Lets the user select the text.
|
||||
+ `textAlign`
|
||||
+ `textAlignVertical`
|
||||
+ `textDecorationLine`
|
||||
+ `textOverflow`
|
||||
+ `textRendering`
|
||||
+ `textOverflow` ‡
|
||||
+ `textRendering` ‡
|
||||
+ `textShadowColor`
|
||||
+ `textShadowOffset`
|
||||
+ `textShadowRadius`
|
||||
+ `textTransform`
|
||||
+ `unicodeBidi`
|
||||
+ `textTransform` ‡
|
||||
+ `unicodeBidi` ‡
|
||||
+ `whiteSpace`
|
||||
+ `wordWrap`
|
||||
+ `wordWrap` ‡
|
||||
+ `writingDirection`
|
||||
|
||||
‡ web only.
|
||||
|
||||
**testID**: string
|
||||
|
||||
Used to locate this view in end-to-end tests.
|
||||
|
||||
@@ -144,7 +144,9 @@ If `true`, all text will automatically be selected on focus.
|
||||
**style**: style
|
||||
|
||||
+ ...[Text#style](./Text.md)
|
||||
+ `outline`
|
||||
+ `resize` ‡
|
||||
|
||||
‡ web only.
|
||||
|
||||
**testID**: string
|
||||
|
||||
|
||||
@@ -99,23 +99,23 @@ from `style`.
|
||||
+ `alignContent`
|
||||
+ `alignItems`
|
||||
+ `alignSelf`
|
||||
+ `animationDelay`
|
||||
+ `animationDirection`
|
||||
+ `animationDuration`
|
||||
+ `animationFillMode`
|
||||
+ `animationIterationCount`
|
||||
+ `animationName`
|
||||
+ `animationPlayState`
|
||||
+ `animationTimingFunction`
|
||||
+ `animationDelay` ‡
|
||||
+ `animationDirection` ‡
|
||||
+ `animationDuration` ‡
|
||||
+ `animationFillMode` ‡
|
||||
+ `animationIterationCount` ‡
|
||||
+ `animationName` ‡
|
||||
+ `animationPlayState` ‡
|
||||
+ `animationTimingFunction` ‡
|
||||
+ `backfaceVisibility`
|
||||
+ `backgroundAttachment`
|
||||
+ `backgroundClip`
|
||||
+ `backgroundAttachment` ‡
|
||||
+ `backgroundClip` ‡
|
||||
+ `backgroundColor`
|
||||
+ `backgroundImage`
|
||||
+ `backgroundOrigin`
|
||||
+ `backgroundPosition`
|
||||
+ `backgroundRepeat`
|
||||
+ `backgroundSize`
|
||||
+ `backgroundImage` ‡
|
||||
+ `backgroundOrigin` ‡
|
||||
+ `backgroundPosition` ‡
|
||||
+ `backgroundRepeat` ‡
|
||||
+ `backgroundSize` ‡
|
||||
+ `borderColor` (single value)
|
||||
+ `borderTopColor`
|
||||
+ `borderBottomColor`
|
||||
@@ -139,7 +139,8 @@ from `style`.
|
||||
+ `bottom`
|
||||
+ `boxShadow`
|
||||
+ `boxSizing`
|
||||
+ `cursor`
|
||||
+ `cursor` ‡
|
||||
+ `display` ‡
|
||||
+ `flex` (number)
|
||||
+ `flexBasis`
|
||||
+ `flexDirection`
|
||||
@@ -162,9 +163,10 @@ from `style`.
|
||||
+ `minWidth`
|
||||
+ `opacity`
|
||||
+ `order`
|
||||
+ `outline` ‡
|
||||
+ `overflow`
|
||||
+ `overflowX`
|
||||
+ `overflowY`
|
||||
+ `overflowX` ‡
|
||||
+ `overflowY` ‡
|
||||
+ `padding` (single value)
|
||||
+ `paddingBottom`
|
||||
+ `paddingHorizontal`
|
||||
@@ -172,22 +174,25 @@ from `style`.
|
||||
+ `paddingRight`
|
||||
+ `paddingTop`
|
||||
+ `paddingVertical`
|
||||
+ `perspective`
|
||||
+ `perspectiveOrigin`
|
||||
+ `perspective` ‡
|
||||
+ `perspectiveOrigin` ‡
|
||||
+ `position`
|
||||
+ `right`
|
||||
+ `top`
|
||||
+ `transform`
|
||||
+ `transformOrigin`
|
||||
+ `transitionDelay`
|
||||
+ `transitionDuration`
|
||||
+ `transitionProperty`
|
||||
+ `transitionTimingFunction`
|
||||
+ `userSelect`
|
||||
+ `visibility`
|
||||
+ `transformOrigin` ‡
|
||||
+ `transitionDelay` ‡
|
||||
+ `transitionDuration` ‡
|
||||
+ `transitionProperty` ‡
|
||||
+ `transitionTimingFunction` ‡
|
||||
+ `userSelect` ‡
|
||||
+ `visibility` ‡
|
||||
+ `width`
|
||||
+ `willChange` ‡
|
||||
+ `zIndex`
|
||||
|
||||
‡ web only.
|
||||
|
||||
Default:
|
||||
|
||||
```js
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-web",
|
||||
"version": "0.0.72",
|
||||
"version": "0.0.73",
|
||||
"description": "React Native for Web",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
|
||||
@@ -11,6 +11,7 @@ import { PropTypes } from 'react'
|
||||
import ImageStylePropTypes from '../../components/Image/ImageStylePropTypes'
|
||||
import ReactPropTypeLocations from 'react-dom/lib/ReactPropTypeLocations'
|
||||
import ReactPropTypesSecret from 'react-dom/lib/ReactPropTypesSecret'
|
||||
import TextInputStylePropTypes from '../../components/TextInput/TextInputStylePropTypes'
|
||||
import TextStylePropTypes from '../../components/Text/TextStylePropTypes'
|
||||
import ViewStylePropTypes from '../../components/View/ViewStylePropTypes'
|
||||
import warning from 'fbjs/lib/warning'
|
||||
@@ -66,17 +67,16 @@ var allStylePropTypes = {};
|
||||
|
||||
StyleSheetValidation.addValidStylePropTypes(ImageStylePropTypes)
|
||||
StyleSheetValidation.addValidStylePropTypes(TextStylePropTypes)
|
||||
StyleSheetValidation.addValidStylePropTypes(TextInputStylePropTypes)
|
||||
StyleSheetValidation.addValidStylePropTypes(ViewStylePropTypes)
|
||||
StyleSheetValidation.addValidStylePropTypes({
|
||||
appearance: PropTypes.string,
|
||||
clear: PropTypes.string,
|
||||
cursor: PropTypes.string,
|
||||
display: PropTypes.string,
|
||||
float: PropTypes.oneOf([ 'left', 'none', 'right' ]),
|
||||
font: PropTypes.string, /* @private */
|
||||
listStyle: PropTypes.string,
|
||||
pointerEvents: PropTypes.string,
|
||||
WebkitOverflowScrolling: PropTypes.string /* @private */
|
||||
pointerEvents: PropTypes.string
|
||||
})
|
||||
|
||||
module.exports = StyleSheetValidation
|
||||
|
||||
@@ -12,6 +12,7 @@ const WritingDirectionPropType = oneOf([ 'auto', 'ltr', 'rtl' ]);
|
||||
const TextOnlyStylePropTypes = {
|
||||
color: ColorPropType,
|
||||
fontFamily: string,
|
||||
fontFeatureSettings: string,
|
||||
fontSize: numberOrString,
|
||||
fontStyle: string,
|
||||
fontWeight: string,
|
||||
|
||||
14
src/components/TextInput/TextInputStylePropTypes.js
Normal file
14
src/components/TextInput/TextInputStylePropTypes.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import TextStylePropTypes from '../Text/TextStylePropTypes';
|
||||
import { PropTypes } from 'react';
|
||||
|
||||
const { oneOf } = PropTypes;
|
||||
|
||||
const TextInputOnlyStylePropTypes = {
|
||||
/* @platform web */
|
||||
resize: oneOf([ 'none', 'vertical', 'horizontal', 'both' ])
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
...TextStylePropTypes,
|
||||
...TextInputOnlyStylePropTypes
|
||||
};
|
||||
@@ -5,7 +5,7 @@ import createDOMElement from '../../modules/createDOMElement';
|
||||
import findNodeHandle from '../../modules/findNodeHandle';
|
||||
import StyleSheet from '../../apis/StyleSheet';
|
||||
import StyleSheetPropType from '../../propTypes/StyleSheetPropType';
|
||||
import TextStylePropTypes from '../Text/TextStylePropTypes';
|
||||
import TextInputStylePropTypes from './TextInputStylePropTypes';
|
||||
import TextareaAutosize from 'react-textarea-autosize';
|
||||
import TextInputState from './TextInputState';
|
||||
import ViewPropTypes from '../View/ViewPropTypes';
|
||||
@@ -84,7 +84,7 @@ class TextInput extends Component {
|
||||
start: PropTypes.number.isRequired,
|
||||
end: PropTypes.number
|
||||
}),
|
||||
style: StyleSheetPropType(TextStylePropTypes),
|
||||
style: StyleSheetPropType(TextInputStylePropTypes),
|
||||
value: PropTypes.string
|
||||
};
|
||||
|
||||
@@ -277,7 +277,8 @@ const styles = StyleSheet.create({
|
||||
boxSizing: 'border-box',
|
||||
color: 'inherit',
|
||||
font: 'inherit',
|
||||
padding: 0
|
||||
padding: 0,
|
||||
resize: 'none'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ module.exports = {
|
||||
backgroundSize: string,
|
||||
boxShadow: string,
|
||||
cursor: string,
|
||||
display: string,
|
||||
outline: string,
|
||||
overflowX: autoOrHiddenOrVisible,
|
||||
overflowY: autoOrHiddenOrVisible,
|
||||
@@ -45,6 +44,6 @@ module.exports = {
|
||||
transitionTimingFunction: string,
|
||||
userSelect: string,
|
||||
visibility: hiddenOrVisible,
|
||||
WebkitOverflowScrolling: oneOf([ 'auto', 'touch' ]),
|
||||
willChange: string
|
||||
willChange: string,
|
||||
WebkitOverflowScrolling: oneOf([ 'auto', 'touch' ])
|
||||
};
|
||||
|
||||
@@ -18,6 +18,9 @@ import View from './components/View';
|
||||
|
||||
// modules
|
||||
import createDOMElement from './modules/createDOMElement';
|
||||
import modality from './modules/modality';
|
||||
|
||||
modality();
|
||||
|
||||
const ReactNativeCore = {
|
||||
createDOMElement,
|
||||
|
||||
@@ -39,6 +39,7 @@ import View from './components/View';
|
||||
|
||||
// modules
|
||||
import createDOMElement from './modules/createDOMElement';
|
||||
import modality from './modules/modality';
|
||||
import NativeModules from './modules/NativeModules';
|
||||
|
||||
// propTypes
|
||||
@@ -46,6 +47,8 @@ import ColorPropType from './propTypes/ColorPropType';
|
||||
import EdgeInsetsPropType from './propTypes/EdgeInsetsPropType';
|
||||
import PointPropType from './propTypes/PointPropType';
|
||||
|
||||
modality();
|
||||
|
||||
const ReactNative = {
|
||||
// top-level API
|
||||
findNodeHandle,
|
||||
|
||||
97
src/modules/modality/index.js
Normal file
97
src/modules/modality/index.js
Normal file
@@ -0,0 +1,97 @@
|
||||
/* global document, window */
|
||||
|
||||
/**
|
||||
* Adapts focus styles based on the user's active input modality (i.e., how
|
||||
* they are interacting with the UI right now).
|
||||
*
|
||||
* Focus styles are only relevant when using the keyboard to interact with the
|
||||
* page. If we only show the focus ring when relevant, we can avoid user
|
||||
* confusion without compromising accessibility.
|
||||
*
|
||||
* The script uses two heuristics to determine whether the keyboard is being used:
|
||||
*
|
||||
* 1. a keydown event occurred immediately before a focus event;
|
||||
* 2. a focus event happened on an element which requires keyboard interaction (e.g., a text field);
|
||||
*
|
||||
* Based on https://github.com/WICG/modality
|
||||
*/
|
||||
const modality = () => {
|
||||
/**
|
||||
* Determine whether the keyboard is required when an element is focused
|
||||
*/
|
||||
const proto = window.Element.prototype;
|
||||
const matcher = proto.matches || proto.mozMatchesSelector || proto.msMatchesSelector || proto.webkitMatchesSelector;
|
||||
const keyboardModalityWhitelist = [
|
||||
'input:not([type])',
|
||||
'input[type=text]',
|
||||
'input[type=number]',
|
||||
'input[type=date]',
|
||||
'input[type=time]',
|
||||
'input[type=datetime]',
|
||||
'textarea',
|
||||
'[role=textbox]',
|
||||
// indicates that a custom element supports the keyboard
|
||||
'[supports-modality=keyboard]'
|
||||
].join(',');
|
||||
|
||||
const focusTriggersKeyboardModality = (el) => {
|
||||
if (matcher) {
|
||||
return matcher.call(el, keyboardModalityWhitelist) && matcher.call(el, ':not([readonly])');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the focus ring by default
|
||||
*/
|
||||
const id = 'modality__';
|
||||
const style = `<style id="${id}">:focus { outline: none; }</style>`;
|
||||
document.head.insertAdjacentHTML('afterbegin', style);
|
||||
const styleElement = document.getElementById(id);
|
||||
|
||||
const disableFocus = () => {
|
||||
if (styleElement) {
|
||||
styleElement.disabled = false;
|
||||
}
|
||||
};
|
||||
|
||||
const enableFocus = () => {
|
||||
if (styleElement) {
|
||||
styleElement.disabled = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Manage the modality focus state
|
||||
*/
|
||||
let keyboardTimer;
|
||||
let hadKeyboardEvent = false;
|
||||
|
||||
// track when the keyboard is in use
|
||||
document.body.addEventListener('keydown', () => {
|
||||
hadKeyboardEvent = true;
|
||||
if (keyboardTimer) {
|
||||
clearTimeout(keyboardTimer);
|
||||
}
|
||||
keyboardTimer = setTimeout(() => {
|
||||
hadKeyboardEvent = false;
|
||||
}, 100);
|
||||
}, true);
|
||||
|
||||
// disable focus style reset when the keyboard is in use
|
||||
document.body.addEventListener('focus', (e) => {
|
||||
if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {
|
||||
enableFocus();
|
||||
}
|
||||
}, true);
|
||||
|
||||
// enable focus style reset when keyboard is no longer in use
|
||||
document.body.addEventListener('blur', () => {
|
||||
if (!hadKeyboardEvent) {
|
||||
disableFocus();
|
||||
}
|
||||
}, true);
|
||||
};
|
||||
|
||||
export default modality;
|
||||
@@ -11,6 +11,7 @@ const LayoutPropTypes = {
|
||||
borderRightWidth: numberOrString,
|
||||
borderTopWidth: numberOrString,
|
||||
boxSizing: string,
|
||||
display: string,
|
||||
height: numberOrString,
|
||||
margin: numberOrString,
|
||||
marginBottom: numberOrString,
|
||||
|
||||
Reference in New Issue
Block a user