mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-06-08 04:31:19 +00:00
[change] modernize Text
Rewrite Text to use function components and hooks.
This commit is contained in:
+46
-42
@@ -10,66 +10,45 @@
|
|||||||
|
|
||||||
import type { TextProps } from './types';
|
import type { TextProps } from './types';
|
||||||
|
|
||||||
import applyLayout from '../../modules/applyLayout';
|
|
||||||
import applyNativeMethods from '../../modules/applyNativeMethods';
|
|
||||||
import createElement from '../createElement';
|
import createElement from '../createElement';
|
||||||
import css from '../StyleSheet/css';
|
import css from '../StyleSheet/css';
|
||||||
import filterSupportedProps from '../View/filterSupportedProps';
|
import filterSupportedProps from '../View/filterSupportedProps';
|
||||||
import React from 'react';
|
import setAndForwardRef from '../../modules/setAndForwardRef';
|
||||||
|
import useElementLayout from '../../hooks/useElementLayout';
|
||||||
|
import usePlatformMethods from '../../hooks/usePlatformMethods';
|
||||||
|
import React, { forwardRef, useContext, useRef } from 'react';
|
||||||
import StyleSheet from '../StyleSheet';
|
import StyleSheet from '../StyleSheet';
|
||||||
import TextAncestorContext from './TextAncestorContext';
|
import TextAncestorContext from './TextAncestorContext';
|
||||||
|
|
||||||
class Text extends React.Component<TextProps> {
|
const Text = forwardRef<TextProps, *>((props, ref) => {
|
||||||
static displayName = 'Text';
|
const { dir, forwardedRef, numberOfLines, onLayout, onPress, selectable } = props;
|
||||||
|
|
||||||
renderText(hasTextAncestor) {
|
const hasTextAncestor = useContext(TextAncestorContext);
|
||||||
const { dir, forwardedRef, numberOfLines, onPress, selectable, style } = this.props;
|
const hostRef = useRef(null);
|
||||||
|
const setRef = setAndForwardRef({
|
||||||
const supportedProps = filterSupportedProps(this.props);
|
getForwardedRef: () => forwardedRef,
|
||||||
|
setLocalRef: c => {
|
||||||
if (onPress) {
|
hostRef.current = c;
|
||||||
supportedProps.accessible = true;
|
|
||||||
supportedProps.onClick = this._createPressHandler(onPress);
|
|
||||||
supportedProps.onKeyDown = this._createEnterHandler(onPress);
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
supportedProps.classList = [
|
const classList = [
|
||||||
classes.text,
|
classes.text,
|
||||||
hasTextAncestor === true && classes.textHasAncestor,
|
hasTextAncestor === true && classes.textHasAncestor,
|
||||||
numberOfLines === 1 && classes.textOneLine,
|
numberOfLines === 1 && classes.textOneLine,
|
||||||
numberOfLines != null && numberOfLines > 1 && classes.textMultiLine
|
numberOfLines != null && numberOfLines > 1 && classes.textMultiLine
|
||||||
];
|
];
|
||||||
// allow browsers to automatically infer the language writing direction
|
const style = [
|
||||||
supportedProps.dir = dir !== undefined ? dir : 'auto';
|
props.style,
|
||||||
supportedProps.ref = forwardedRef;
|
|
||||||
supportedProps.style = [
|
|
||||||
style,
|
|
||||||
numberOfLines != null && numberOfLines > 1 && { WebkitLineClamp: numberOfLines },
|
numberOfLines != null && numberOfLines > 1 && { WebkitLineClamp: numberOfLines },
|
||||||
selectable === false && styles.notSelectable,
|
selectable === false && styles.notSelectable,
|
||||||
onPress && styles.pressable
|
onPress && styles.pressable
|
||||||
];
|
];
|
||||||
|
|
||||||
const component = hasTextAncestor ? 'span' : 'div';
|
useElementLayout(hostRef, onLayout);
|
||||||
|
usePlatformMethods(hostRef, ref, classList, style);
|
||||||
|
|
||||||
return createElement(component, supportedProps);
|
function createEnterHandler(fn) {
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<TextAncestorContext.Consumer>
|
|
||||||
{hasTextAncestor => {
|
|
||||||
const element = this.renderText(hasTextAncestor);
|
|
||||||
return hasTextAncestor ? (
|
|
||||||
element
|
|
||||||
) : (
|
|
||||||
<TextAncestorContext.Provider value={true}>{element}</TextAncestorContext.Provider>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</TextAncestorContext.Consumer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
_createEnterHandler(fn) {
|
|
||||||
return e => {
|
return e => {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
fn && fn(e);
|
fn && fn(e);
|
||||||
@@ -77,14 +56,39 @@ class Text extends React.Component<TextProps> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_createPressHandler(fn) {
|
function createPressHandler(fn) {
|
||||||
return e => {
|
return e => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
fn && fn(e);
|
fn && fn(e);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const supportedProps = filterSupportedProps(props);
|
||||||
|
|
||||||
|
if (onPress) {
|
||||||
|
supportedProps.accessible = true;
|
||||||
|
supportedProps.onClick = createPressHandler(onPress);
|
||||||
|
supportedProps.onKeyDown = createEnterHandler(onPress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
supportedProps.classList = classList;
|
||||||
|
// allow browsers to automatically infer the language writing direction
|
||||||
|
supportedProps.dir = dir !== undefined ? dir : 'auto';
|
||||||
|
supportedProps.ref = setRef;
|
||||||
|
supportedProps.style = style;
|
||||||
|
|
||||||
|
const component = hasTextAncestor ? 'span' : 'div';
|
||||||
|
const element = createElement(component, supportedProps);
|
||||||
|
|
||||||
|
return hasTextAncestor ? (
|
||||||
|
element
|
||||||
|
) : (
|
||||||
|
<TextAncestorContext.Provider value={true}>{element}</TextAncestorContext.Provider>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
Text.displayName = 'Text';
|
||||||
|
|
||||||
const classes = css.create({
|
const classes = css.create({
|
||||||
text: {
|
text: {
|
||||||
border: '0 solid black',
|
border: '0 solid black',
|
||||||
@@ -127,4 +131,4 @@ const styles = StyleSheet.create({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default applyLayout(applyNativeMethods(Text));
|
export default Text;
|
||||||
|
|||||||
+11
-10
@@ -37,7 +37,7 @@ function createHitSlopElement(hitSlop) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const View = forwardRef<ViewProps, *>((props, ref) => {
|
const View = forwardRef<ViewProps, *>((props, ref) => {
|
||||||
const { forwardedRef, hitSlop, onLayout, style, ...rest } = props;
|
const { children, forwardedRef, hitSlop, onLayout } = props;
|
||||||
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
React.Children.toArray(props.children).forEach(item => {
|
React.Children.toArray(props.children).forEach(item => {
|
||||||
@@ -47,10 +47,8 @@ const View = forwardRef<ViewProps, *>((props, ref) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const classList = [classes.view];
|
|
||||||
const hasTextAncestor = useContext(TextAncestorContext);
|
const hasTextAncestor = useContext(TextAncestorContext);
|
||||||
const hostRef = useRef(null);
|
const hostRef = useRef(null);
|
||||||
|
|
||||||
const setRef = setAndForwardRef({
|
const setRef = setAndForwardRef({
|
||||||
getForwardedRef: () => forwardedRef,
|
getForwardedRef: () => forwardedRef,
|
||||||
setLocalRef: c => {
|
setLocalRef: c => {
|
||||||
@@ -58,19 +56,22 @@ const View = forwardRef<ViewProps, *>((props, ref) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const classList = [classes.view];
|
||||||
|
const style = StyleSheet.compose(
|
||||||
|
hasTextAncestor && styles.inline,
|
||||||
|
props.style
|
||||||
|
);
|
||||||
|
|
||||||
useElementLayout(hostRef, onLayout);
|
useElementLayout(hostRef, onLayout);
|
||||||
usePlatformMethods(hostRef, ref, classList, style);
|
usePlatformMethods(hostRef, ref, classList, style);
|
||||||
|
|
||||||
const supportedProps = filterSupportedProps(rest);
|
const supportedProps = filterSupportedProps(props);
|
||||||
supportedProps.children = hitSlop
|
supportedProps.children = hitSlop
|
||||||
? React.Children.toArray([createHitSlopElement(hitSlop), props.children])
|
? React.Children.toArray([createHitSlopElement(hitSlop), children])
|
||||||
: props.children;
|
: children;
|
||||||
supportedProps.classList = classList;
|
supportedProps.classList = classList;
|
||||||
supportedProps.ref = setRef;
|
supportedProps.ref = setRef;
|
||||||
supportedProps.style = StyleSheet.compose(
|
supportedProps.style = style;
|
||||||
hasTextAncestor && styles.inline,
|
|
||||||
style
|
|
||||||
);
|
|
||||||
|
|
||||||
return createElement('div', supportedProps);
|
return createElement('div', supportedProps);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { useImperativeHandle, useRef } from 'react';
|
|||||||
export default function usePlatformMethods(
|
export default function usePlatformMethods(
|
||||||
hostRef: ElementRef<any>,
|
hostRef: ElementRef<any>,
|
||||||
ref: ElementRef<any>,
|
ref: ElementRef<any>,
|
||||||
classList: Array<string>,
|
classList: Array<boolean | string>,
|
||||||
style: GenericStyleProp<any>
|
style: GenericStyleProp<any>
|
||||||
) {
|
) {
|
||||||
const previousStyle = useRef(null);
|
const previousStyle = useRef(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user