Skip to content

feat(Rating):增加自定义每项的提示信息 & 更新文档 #326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 41 additions & 25 deletions example/examples/src/routes/Rating/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {Component} from 'react';
import {StyleSheet, View} from 'react-native';
import {View} from 'react-native';
import Layout, {Container} from '../../Layout';
import {Rating, Icon} from '@uiw/react-native';
import {ComProps} from '../../routes';
Expand All @@ -10,7 +10,8 @@ export interface IndexProps extends ComProps {}
export interface IndexState {
visible: boolean;
}

const desc = ['', '1星', '2星', '3星', '4星', '5星'];
const descs = ['terrible', 'bad', 'normal', 'good', 'wonderful', 'perfect'];
export default class Index extends Component<IndexProps, IndexState> {
static state: IndexState;
constructor(props: IndexProps) {
Expand All @@ -31,33 +32,48 @@ export default class Index extends Component<IndexProps, IndexState> {
<Layout>
<Header title={title} description={description} />
<Body>
<View style={styles.divider} />
<Rating
defaultRating={2}
resultRating={10}
icon={{
unactived: <Icon name="star-off" />,
actived: <Icon name="star-on" />,
}}
onPress={console.log}
/>
<View style={styles.divider} />
<Rating />
<Card title="基本使用">
<Rating />
</Card>
<Card title="指定 Icon">
<Rating
defaultRating={3}
icon={{
unactived: <Icon name="smile-o" fill="red" />,
actived: <Icon name="smile" fill="red" />,
}}
onPress={console.log}
/>
</Card>
<Card title="默认选中及总数">
<Rating
defaultRating={2}
resultRating={10}
icon={{
unactived: <Icon name="star-off" />,
actived: <Icon name="star-on" />,
}}
onPress={console.log}
/>
</Card>
<Card title="评分组件加上文案展示">
<Rating tooltips={desc} defaultRating={1} />
</Card>
<Card title="评分文案样式修改">
<Rating
tooltips={descs}
defaultRating={3}
color="blue"
tooltipsStyle={{fontSize: 25, color: 'blue'}}
/>
</Card>
<Card title="只读">
<Rating defaultRating={3} color="green" disabled />
</Card>
</Body>
<Footer />
</Layout>
</Container>
);
}
}

const styles = StyleSheet.create({
card: {
backgroundColor: '#fff',
paddingLeft: 20,
paddingRight: 20,
},
divider: {
marginVertical: 10,
},
});
60 changes: 59 additions & 1 deletion packages/core/src/Rating/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Rating 评分

在你想用任意需要评分的的地方使用。

<img src='https://user-images.githubusercontent.com/66067296/140004186-31b369e2-13f1-4dd2-aef5-331aa133b0fe.gif' alt='Rating' style='zoom:33%;' />
<img src='https://user-images.githubusercontent.com/66067296/140290956-1328745e-63da-4d17-8db9-238c18078272.gif' alt='Rating' style='zoom:33%;' />

### 基础示例

Expand Down Expand Up @@ -44,6 +44,58 @@ function Demo() {
}
```

### 默认选中及总数

```jsx
import { Fragment } from 'react';
import { Rating, Icon } from '@uiw/react-native';
function Demo() {
return (
<Fragment>
<Rating
defaultRating={3}
resultRating={10}
icon={{
unactived: <Icon name="smile-o" fill="red" />,
actived: <Icon name="smile" fill="red" />,
}}
onPress={console.log}
/>
</Fragment>
);
}
```

### 评分组件加上文案展示及样式修改

```jsx
import { Fragment } from 'react';
import { Rating, Icon } from '@uiw/react-native';
function Demo() {
const desc = ['0星', '1星', '2星', '3星', '4星', '5星'];
return (
<Fragment>
<Rating tooltips={desc} tooltipsStyle={{ fontSize: 25, color: 'blue' }} />
</Fragment>
);
}
```

### 只读

```jsx
import { Fragment } from 'react';
import { Rating, Icon } from '@uiw/react-native';
function Demo() {
const desc = ['0星', '1星', '2星', '3星', '4星', '5星'];
return (
<Fragment>
<Rating defaultRating={3} color="green" disabled />
</Fragment>
);
}
```

### Props

```ts
Expand All @@ -69,5 +121,11 @@ export interface RatingProps {
* @param score type: number 选中几个
*/
onPress?: (score: number) => void;
/** 自定义每项的提示信息 */
tooltips?: string[];
/** 自定义提示信息样式 */
tooltipsStyle?: StyleProp<TextStyle>;
/** 只读模式 */
disabled: boolean
}
```
49 changes: 40 additions & 9 deletions packages/core/src/Rating/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { View, StyleSheet, TouchableOpacity } from 'react-native';
import { View, StyleSheet, TouchableOpacity, Text, StyleProp, TextStyle } from 'react-native';

import Icon, { IconsName } from '../Icon';
import { TabsItemIconTypes } from '../Tabs/TabsItem';
Expand All @@ -24,6 +24,12 @@ export interface RatingProps {
* @param score type: number 得到几分
*/
onPress?: (score: number) => void;
/** 自定义每项的提示信息 */
tooltips?: string[];
/** 自定义提示信息样式 */
tooltipsStyle?: StyleProp<TextStyle>;
/** 只读模式 */
disabled: boolean;
}

export interface RatingState {
Expand All @@ -33,66 +39,87 @@ export interface RatingState {
color: string;
defaultRating: number;
typeIcon: icoType;
tooltips?: string[];
tooltipsText?: string;
disabled: boolean;
}

export default class Rating extends React.Component<RatingProps, RatingState> {
constructor(props: RatingProps) {
super(props);
let start = (props.icon && props.icon.unactived) || 'star-off';
let end = (props.icon && props.icon.actived) || 'star-on';

this.state = {
defaultRating: props.defaultRating || 0,
resultRating: props.resultRating || 5,
icon: [],
size: props.size ?? 24,
color: props.color || '#ebc445',
typeIcon: [start, end],
tooltips: props.tooltips,
tooltipsText: '',
disabled: false,
};
}
componentDidMount() {
const { defaultRating } = this.state;
this.updateIcon(defaultRating);
}

flag = true;
updateIcon = (index: number) => {
const { resultRating } = this.state;
const { onPress } = this.props;
const { onPress, disabled } = this.props;
let start = this.state.typeIcon[0];
let end = this.state.typeIcon[1];
if (disabled) {
this.setState({ disabled: disabled });
}
if (index === 1 && this.flag) {
this.setState({ icon: [...new Array(index).fill(end), ...new Array(resultRating - index).fill(start)] });
onPress?.(1);
if (this.state.tooltips) {
this.setState({ tooltipsText: this.state.tooltips[index] });
}
this.flag = false;
} else if (index === 1 && !this.flag) {
this.setState({ icon: [...new Array(index - 1).fill(end), ...new Array(resultRating - index + 1).fill(start)] });
if (this.state.tooltips) {
this.setState({ tooltipsText: this.state.tooltips[index - 1] });
}
this.flag = true;
onPress?.(0);
} else {
this.setState({ icon: [...new Array(index).fill(end), ...new Array(resultRating - index).fill(start)] });
if (this.state.tooltips) {
this.setState({ tooltipsText: this.state.tooltips[index] });
}
this.flag = true;
onPress?.(index);
}
};
render() {
const { icon, size, color, tooltipsText, disabled } = this.state;
const { tooltipsStyle } = this.props;
return (
<View>
<View style={styles.RatingContainer}>
{this.state.icon.map((item, index) => {
{icon.map((item, index) => {
return (
<TouchableOpacity
onPress={() => {
this.updateIcon(index + 1);
if (disabled === false) {
this.updateIcon(index + 1);
}
}}
key={index}
>
{typeof item === 'string' ? (
<Icon name={item as IconsName} color="#ebc445" size={this.state.size} />
) : (
item
)}
{typeof item === 'string' ? <Icon name={item as IconsName} color={color} size={size} /> : item}
</TouchableOpacity>
);
})}
<Text style={[styles.tooltipsText, { fontSize: size - 5, color: color }, tooltipsStyle]}>{tooltipsText}</Text>
</View>
</View>
);
Expand All @@ -102,5 +129,9 @@ export default class Rating extends React.Component<RatingProps, RatingState> {
const styles = StyleSheet.create({
RatingContainer: {
flexDirection: 'row',
alignItems: 'center',
},
tooltipsText: {
marginHorizontal: 10,
},
});