Skip to content

Commit a7ca94f

Browse files
committed
feat(RnText):新增RnText组件
1 parent 6caec7c commit a7ca94f

File tree

7 files changed

+245
-28
lines changed

7 files changed

+245
-28
lines changed

example/examples/src/routes/Typography/index.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
Div,
1717
Hr,
1818
Em,
19+
RnText,
1920
} from '@uiw/react-native';
2021
import {ComProps} from '../../routes';
2122
import Layout, {Container} from '../../Layout';
@@ -73,6 +74,19 @@ export default class TypographyView extends React.Component<TypographyViewProps>
7374
<Hr />
7475
<Text>一段文本</Text>
7576
</Card>
77+
<Card title="可高亮文字<RnText />">
78+
<RnText type="header" label="react-native-uiw" />
79+
<RnText type="title" label="react-native-uiw" />
80+
<RnText type="label" label="react-native-uiw" />
81+
<RnText type="subLabel" label="react-native-uiw" />
82+
<RnText
83+
type="header"
84+
uppercase
85+
label="react-native-uiw"
86+
highlightText="native"
87+
highlightTextStyle={{fontSize: 24, color: 'red'}}
88+
/>
89+
</Card>
7690
</Body>
7791
<Footer />
7892
</Layout>

packages/core/src/SelectCascader/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { View, Text, StyleSheet, TouchableHighlight, StyleProp, TextStyle, ViewStyle } from 'react-native';
22
import React, { Component } from 'react';
33
import { Picker } from '@react-native-picker/picker';
4-
import arrayTreeFilter from '../utils/arrayTreeFilter';
4+
import { arrayTreeFilter } from '../utils/utils';
55
import Modal from '../Modal';
66
import { colors } from '../utils';
77

packages/core/src/Typography/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,20 @@ function Demo() {
130130
);
131131
}
132132
```
133+
134+
```jsx
135+
import { View } from 'react-native';
136+
import { RnText } from '@uiw/react-native';
137+
138+
function Demo() {
139+
return (
140+
<View>
141+
<RnText type="header" label="react-native-uiw" />
142+
<RnText type="title" label="react-native-uiw" />
143+
<RnText type="label" label="react-native-uiw" />
144+
<RnText type="subLabel" label="react-native-uiw" />
145+
<RnText type="header" label="react-native-uiw" highlightText="native" highlightTextStyle={{ fontSize: 24, color: "red" }} />
146+
</View>
147+
);
148+
}
149+
```
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import React from 'react';
2+
import { Text as RNText, StyleSheet, TextProps as RNTextProps, TextStyle, Animated, StyleProp } from 'react-native';
3+
import _ from 'lodash';
4+
import { rnTextType, getTextPartsByHighlight } from '../utils/utils';
5+
6+
export type RnTextProps = RNTextProps & {
7+
// header:Header标题 | title:列表/From标题 | label:正文,说明,备注label | subLabel:辅助性文字
8+
type?: 'header' | 'title' | 'label' | 'subLabel';
9+
// 文本正文
10+
label?: string;
11+
// 文本颜色
12+
color?: string;
13+
// 文本居中
14+
center?: boolean;
15+
// 将文本转换为全大写
16+
uppercase?: boolean;
17+
animated?: boolean;
18+
// 高亮的文本
19+
highlightText?: string;
20+
// 高亮文本样式
21+
highlightTextStyle?: TextStyle;
22+
// 背景色
23+
backgroundColor?: any;
24+
children?: React.ReactNode;
25+
style?: StyleProp<TextStyle | Animated.AnimatedProps<TextStyle>>;
26+
};
27+
28+
export default (props: RnTextProps) => {
29+
const {
30+
type,
31+
color,
32+
center,
33+
uppercase,
34+
animated,
35+
backgroundColor,
36+
style,
37+
children,
38+
label,
39+
highlightText,
40+
highlightTextStyle,
41+
...others
42+
} = props;
43+
44+
const TextContainer: React.ClassType<any, any, any> = animated ? Animated.createAnimatedComponent(RNText) : RNText;
45+
46+
/**
47+
* 文本渲染
48+
* @param children
49+
* @returns
50+
*/
51+
const renderText = (children: any): any => {
52+
// 递归渲染子级的Text
53+
if (!_.isEmpty(highlightText)) {
54+
if (_.isArray(children)) {
55+
return children.map((child) => renderText(child));
56+
}
57+
if (_.isString(children)) {
58+
const textParts = getTextPartsByHighlight(children, highlightText);
59+
return textParts.map((text, index) => {
60+
const shouldHighlight = _.lowerCase(text) === _.lowerCase(highlightText);
61+
return (
62+
<RNText key={index} style={shouldHighlight ? [styles.highlight, highlightTextStyle] : styles.notHighlight}>
63+
{text}
64+
</RNText>
65+
);
66+
});
67+
}
68+
}
69+
return children;
70+
};
71+
72+
const textStyle = [
73+
{
74+
...rnTextType(type),
75+
},
76+
styles.container,
77+
color && { color },
78+
backgroundColor && { backgroundColor },
79+
center && styles.centered,
80+
uppercase && styles.uppercase,
81+
style,
82+
];
83+
84+
return (
85+
<TextContainer {...others} style={textStyle}>
86+
{renderText(label || children)}
87+
</TextContainer>
88+
);
89+
};
90+
91+
const styles = StyleSheet.create({
92+
container: {
93+
backgroundColor: 'transparent',
94+
textAlign: 'left',
95+
},
96+
centered: {
97+
textAlign: 'center',
98+
},
99+
uppercase: {
100+
textTransform: 'uppercase',
101+
},
102+
highlight: {
103+
color: '#333333',
104+
fontSize: 14,
105+
},
106+
notHighlight: {
107+
color: undefined,
108+
},
109+
});

packages/core/src/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ export { default as Br } from './Typography/Br';
129129
export { default as Div } from './Typography/Div';
130130
export { default as Hr } from './Typography/Hr';
131131
export { default as Em } from './Typography/Em';
132+
export { default as RnText } from './Typography/RnText';
132133

133134
export * from './Typography/H1';
134135
export * from './Typography/H2';
@@ -145,3 +146,4 @@ export * from './Typography/Br';
145146
export * from './Typography/Div';
146147
export * from './Typography/Hr';
147148
export * from './Typography/Em';
149+
export * from './Typography/RnText';

packages/core/src/utils/arrayTreeFilter.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

packages/core/src/utils/utils.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { TextStyle } from 'react-native';
2+
import _ from 'lodash';
3+
import { colorsPalette } from './colors';
4+
5+
export function arrayTreeFilter<T>(
6+
data: T[],
7+
filterFn: (item: T, level: number) => boolean,
8+
options?: {
9+
childrenKeyName?: string;
10+
},
11+
) {
12+
options = options || {};
13+
options.childrenKeyName = options.childrenKeyName || 'children';
14+
var children = data || [];
15+
var result: T[] = [];
16+
var level = 0;
17+
do {
18+
var foundItem: T = children.filter(function (item) {
19+
return filterFn(item, level);
20+
})[0];
21+
if (!foundItem) {
22+
break;
23+
}
24+
result.push(foundItem);
25+
children = (foundItem as any)[options.childrenKeyName] || [];
26+
level += 1;
27+
} while (children.length > 0);
28+
return result;
29+
}
30+
/**
31+
*
32+
* RnText 类型判断
33+
* @param type "header" | "title" | 'label' | 'subLabel'
34+
* @returns
35+
*/
36+
export function rnTextType(type?: 'header' | 'title' | 'label' | 'subLabel') {
37+
let textStyle: TextStyle = {
38+
color: colorsPalette.grey10,
39+
fontSize: 16,
40+
};
41+
switch (type) {
42+
case 'header':
43+
textStyle = {
44+
color: colorsPalette.grey10,
45+
fontSize: 17,
46+
fontWeight: '500',
47+
};
48+
break;
49+
case 'title':
50+
textStyle = {
51+
color: colorsPalette.grey10,
52+
fontSize: 15,
53+
fontWeight: '400',
54+
};
55+
break;
56+
case 'label':
57+
textStyle = {
58+
color: colorsPalette.grey10,
59+
fontSize: 14,
60+
fontWeight: '300',
61+
};
62+
break;
63+
case 'subLabel':
64+
textStyle = {
65+
color: colorsPalette.grey30,
66+
fontSize: 12,
67+
fontWeight: '300',
68+
};
69+
break;
70+
default:
71+
}
72+
return textStyle;
73+
}
74+
75+
/**
76+
* 处理高亮文本
77+
* @targetString 整体文本
78+
* @highlightText 高亮的文本
79+
* textParts:[]
80+
* */
81+
export const getTextPartsByHighlight = (targetString = '', highlightText = '') => {
82+
if (_.isEmpty(highlightText.trim())) {
83+
return [targetString];
84+
}
85+
86+
const textParts = [];
87+
let highlightIndex;
88+
89+
do {
90+
highlightIndex = targetString.toLowerCase().indexOf(highlightText.toLowerCase());
91+
if (highlightIndex !== -1) {
92+
if (highlightIndex > 0) {
93+
textParts.push(targetString.substring(0, highlightIndex));
94+
}
95+
textParts.push(targetString.substr(highlightIndex, highlightText.length));
96+
targetString = targetString.substr(highlightIndex + highlightText.length);
97+
} else {
98+
textParts.push(targetString);
99+
}
100+
} while (highlightIndex !== -1);
101+
return textParts;
102+
};

0 commit comments

Comments
 (0)