mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-26 07:49:18 +00:00
[fix] add support for TextInput placeholderTextColor prop
This change also ensures that potential object-styles (user-provided or placeholderTextColor) are group together at the end of the style array. Fix #560
This commit is contained in:
+3
-3
@@ -37,6 +37,8 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
|
||||
}
|
||||
@keyframes rn-ActivityIndicator-animation{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg);}}
|
||||
@keyframes rn-ProgressBar-animation{0%{-webkit-transform:translateX(-100%);transform:translateX(-100%);}100%{-webkit-transform:translateX(400%);transform:translateX(400%);}}
|
||||
.rn-pointerEvents-12vffkv > *{pointer-events:auto}
|
||||
.rn-pointerEvents-12vffkv{pointer-events:none !important}
|
||||
.rn-alignItems-1oszu61{-ms-flex-align:stretch;-webkit-align-items:stretch;-webkit-box-align:stretch;align-items:stretch}
|
||||
.rn-borderTopStyle-1efd50x{border-top-style:solid}
|
||||
.rn-borderRightStyle-14skgim{border-right-style:solid}
|
||||
@@ -70,7 +72,5 @@ input::-webkit-inner-spin-button,input::-webkit-outer-spin-button,input::-webkit
|
||||
.rn-left-1d2f490{left:0px}
|
||||
.rn-position-u8s1d{position:absolute}
|
||||
.rn-right-zchlnj{right:0px}
|
||||
.rn-top-ipm5af{top:0px}
|
||||
.rn-pointerEvents-12vffkv > *{pointer-events:auto}
|
||||
.rn-pointerEvents-12vffkv{pointer-events:none !important}"
|
||||
.rn-top-ipm5af{top:0px}"
|
||||
`;
|
||||
|
||||
+6
-6
@@ -158,13 +158,13 @@ export default class ReactNativeStyleResolver {
|
||||
props.classList.push(className);
|
||||
} else {
|
||||
// Certain properties and values are not transformed by 'createReactDOMStyle' as they
|
||||
// require more complex transforms into multiple CSS rules. Here we make sure the styles
|
||||
// can be represented by a className and don't end up as invalid inline-styles.
|
||||
if (styleProp === 'pointerEvents') {
|
||||
// require more complex transforms into multiple CSS rules. Here we assume that StyleManager
|
||||
// can bind these styles to a className, and prevent them becoming invalid inline-styles.
|
||||
if (styleProp === 'pointerEvents' || styleProp === 'placeholderTextColor') {
|
||||
const className = this.styleSheetManager.injectDeclaration(styleProp, value);
|
||||
props.classList.push(className);
|
||||
// } else if (styleProp ==='placeholderTextColor') {
|
||||
// } else if (styleProp ==='animationName') {
|
||||
if (className) {
|
||||
props.classList.push(className);
|
||||
}
|
||||
} else {
|
||||
if (!props.style) {
|
||||
props.style = {};
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`StyleSheet/createAtomicRules transforms custom placeholderTextColor declaration 1`] = `
|
||||
Array [
|
||||
"@media all {
|
||||
.test::-webkit-input-placeholder{color:gray;opacity:1}
|
||||
.test::-moz-placeholder{color:gray;opacity:1}
|
||||
.test:-ms-input-placeholder{color:gray;opacity:1}
|
||||
.test::placeholder{color:gray;opacity:1}
|
||||
}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/createAtomicRules transforms custom pointerEvents declaration 1`] = `
|
||||
Array [
|
||||
".test > *{pointer-events:none}",
|
||||
".test{pointer-events:auto !important}",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`StyleSheet/createAtomicRules transforms standard declarations to a single rule 1`] = `
|
||||
Array [
|
||||
".test{margin:0px}",
|
||||
]
|
||||
`;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/* eslint-env jasmine, jest */
|
||||
|
||||
import createAtomicRules from '../createAtomicRules';
|
||||
|
||||
describe('StyleSheet/createAtomicRules', () => {
|
||||
test('transforms standard declarations to a single rule', () => {
|
||||
expect(createAtomicRules('.test', 'margin', 0)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('transforms custom pointerEvents declaration', () => {
|
||||
expect(createAtomicRules('.test', 'pointerEvents', 'box-only')).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('transforms custom placeholderTextColor declaration', () => {
|
||||
expect(createAtomicRules('.test', 'placeholderTextColor', 'gray')).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -2,29 +2,47 @@ import createRuleBlock from './createRuleBlock';
|
||||
|
||||
const createAtomicRules = (selector, prop, value) => {
|
||||
const rules = [];
|
||||
let val = value;
|
||||
|
||||
// pointerEvents is a special case that requires custom values and additional rules
|
||||
// See #513
|
||||
if (prop === 'pointerEvents') {
|
||||
if (value === 'auto' || value === 'box-only') {
|
||||
val = 'auto !important';
|
||||
if (value === 'box-only') {
|
||||
const block = createRuleBlock({ [prop]: 'none' });
|
||||
rules.push(`${selector} > *{${block}}`);
|
||||
}
|
||||
} else if (value === 'none' || value === 'box-none') {
|
||||
val = 'none !important';
|
||||
if (value === 'box-none') {
|
||||
const block = createRuleBlock({ [prop]: 'auto' });
|
||||
rules.push(`${selector} > *{${block}}`);
|
||||
switch (prop) {
|
||||
// pointerEvents is a special case that requires custom values and additional rules
|
||||
// See #513
|
||||
case 'pointerEvents': {
|
||||
let val = value;
|
||||
if (value === 'auto' || value === 'box-only') {
|
||||
val = 'auto !important';
|
||||
if (value === 'box-only') {
|
||||
const block = createRuleBlock({ [prop]: 'none' });
|
||||
rules.push(`${selector} > *{${block}}`);
|
||||
}
|
||||
} else if (value === 'none' || value === 'box-none') {
|
||||
val = 'none !important';
|
||||
if (value === 'box-none') {
|
||||
const block = createRuleBlock({ [prop]: 'auto' });
|
||||
rules.push(`${selector} > *{${block}}`);
|
||||
}
|
||||
}
|
||||
const block = createRuleBlock({ [prop]: val });
|
||||
rules.push(`${selector}{${block}}`);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'placeholderTextColor': {
|
||||
const block = createRuleBlock({ color: value, opacity: 1 });
|
||||
rules.push(`@media all {
|
||||
${selector}::-webkit-input-placeholder{${block}}
|
||||
${selector}::-moz-placeholder{${block}}
|
||||
${selector}:-ms-input-placeholder{${block}}
|
||||
${selector}::placeholder{${block}}
|
||||
}`);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
const block = createRuleBlock({ [prop]: value });
|
||||
rules.push(`${selector}{${block}}`);
|
||||
}
|
||||
}
|
||||
|
||||
const block = createRuleBlock({ [prop]: val });
|
||||
rules.push(`${selector}{${block}}`);
|
||||
|
||||
return rules;
|
||||
};
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ class TextInput extends Component<*> {
|
||||
onSelectionChange: func,
|
||||
onSubmitEditing: func,
|
||||
placeholder: string,
|
||||
placeholderTextColor: ColorPropType,
|
||||
secureTextEntry: bool,
|
||||
selectTextOnFocus: bool,
|
||||
selection: shape({
|
||||
@@ -126,7 +127,6 @@ class TextInput extends Component<*> {
|
||||
onContentSizeChange: func,
|
||||
onEndEditing: func,
|
||||
onScroll: func,
|
||||
placeholderTextColor: ColorPropType,
|
||||
returnKeyLabel: string,
|
||||
returnKeyType: string,
|
||||
selectionColor: ColorPropType,
|
||||
@@ -198,7 +198,6 @@ class TextInput extends Component<*> {
|
||||
onContentSizeChange,
|
||||
onEndEditing,
|
||||
onScroll,
|
||||
placeholderTextColor,
|
||||
returnKeyLabel,
|
||||
returnKeyType,
|
||||
selectionColor,
|
||||
|
||||
@@ -68,6 +68,7 @@ const createDOMProps = (component, props, styleResolver) => {
|
||||
accessibilityLabel,
|
||||
accessibilityLiveRegion,
|
||||
importantForAccessibility,
|
||||
placeholderTextColor,
|
||||
pointerEvents,
|
||||
style: providedStyle,
|
||||
testID,
|
||||
@@ -89,8 +90,9 @@ const createDOMProps = (component, props, styleResolver) => {
|
||||
role === 'heading' && resetStyles.heading,
|
||||
component === 'ul' && resetStyles.list,
|
||||
role === 'button' && !isDisabled && resetStyles.ariaButton,
|
||||
pointerEvents && pointerEventsStyles[pointerEvents],
|
||||
providedStyle,
|
||||
pointerEvents && pointerEventsStyles[pointerEvents]
|
||||
placeholderTextColor && { placeholderTextColor }
|
||||
];
|
||||
const { className, style } = styleResolver(reactNativeStyle);
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import PropMultiline from './examples/PropMultiline';
|
||||
import PropNumberOfLines from './examples/PropNumberOfLines';
|
||||
import PropOnSelectionChange from './examples/PropOnSelectionChange';
|
||||
import PropPlaceholder from './examples/PropPlaceholder';
|
||||
import PropPlaceholderTextColor from './examples/PropPlaceholderTextColor';
|
||||
import PropSecureTextEntry from './examples/PropSecureTextEntry';
|
||||
import PropSelectTextOnFocus from './examples/PropSelectTextOnFocus';
|
||||
import TextInputEvents from './examples/TextInputEvents';
|
||||
@@ -262,6 +263,15 @@ nativeEvent: { key: keyValue } }`}</Code>{' '}
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="placeholderTextColor"
|
||||
typeInfo="?color"
|
||||
description="The text color of the placeholder string."
|
||||
example={{
|
||||
render: () => <PropPlaceholderTextColor />
|
||||
}}
|
||||
/>
|
||||
|
||||
<DocItem
|
||||
name="secureTextEntry"
|
||||
typeInfo="?boolean = false"
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { styles } from '../helpers';
|
||||
import { TextInput, View } from 'react-native';
|
||||
|
||||
const TextInputPlaceholderTextColorExample = () => (
|
||||
<View>
|
||||
<TextInput
|
||||
placeholder="This is placeholder text"
|
||||
placeholderTextColor="orange"
|
||||
style={styles.textinput}
|
||||
/>
|
||||
<TextInput
|
||||
multiline={true}
|
||||
placeholder="This is placeholder text"
|
||||
placeholderTextColor="red"
|
||||
style={styles.multiline}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
export default TextInputPlaceholderTextColorExample;
|
||||
Reference in New Issue
Block a user