-
Notifications
You must be signed in to change notification settings - Fork 611
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
874 additions
and
431 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,16 @@ | ||
import React from 'react' | ||
import { | ||
ImageStyle, | ||
StyleProp, | ||
Text, | ||
TouchableWithoutFeedback, | ||
View, | ||
ViewStyle, | ||
} from 'react-native' | ||
import { WithTheme, WithThemeStyles } from '../style' | ||
import Checkbox from './Checkbox' | ||
import { CheckboxPropsType } from './PropsType' | ||
import AgreeItemstyles, { CheckboxStyle } from './style/index' | ||
import Checkbox, { CheckboxProps } from './Checkbox' | ||
|
||
export interface AgreeItemProps | ||
extends CheckboxPropsType, | ||
WithThemeStyles<CheckboxStyle> { | ||
checkboxStyle?: StyleProp<ImageStyle> | ||
style?: StyleProp<ViewStyle> | ||
const AgreeItem = (props: CheckboxProps) => { | ||
return ( | ||
<Checkbox | ||
{...props} | ||
styles={{ | ||
checkbox_checked: { borderColor: 'red' }, | ||
checkbox_inner: { backgroundColor: 'red' }, | ||
}} | ||
/> | ||
) | ||
} | ||
|
||
export default class AgreeItem extends React.Component<AgreeItemProps, any> { | ||
checkbox: Checkbox | null | ||
|
||
handleClick = () => { | ||
if (this.checkbox) { | ||
this.checkbox.handleClick() | ||
} | ||
} | ||
|
||
render() { | ||
const { | ||
style, | ||
checkboxStyle, | ||
children, | ||
disabled, | ||
checked, | ||
defaultChecked, | ||
onChange, | ||
} = this.props | ||
|
||
return ( | ||
<WithTheme styles={this.props.styles} themeStyles={AgreeItemstyles}> | ||
{(styles) => { | ||
const contentDom = !children ? null : React.isValidElement( | ||
children, | ||
) ? ( | ||
children | ||
) : ( | ||
<Text>{children}</Text> | ||
) | ||
|
||
return ( | ||
<TouchableWithoutFeedback onPress={this.handleClick}> | ||
<View style={[styles.agreeItem, style]}> | ||
<Checkbox | ||
ref={(ref) => (this.checkbox = ref)} | ||
style={[styles.agreeItemCheckbox, checkboxStyle]} | ||
disabled={disabled} | ||
checked={checked} | ||
defaultChecked={defaultChecked} | ||
onChange={onChange} | ||
/> | ||
<View style={{ flex: 1 }}>{contentDom}</View> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
) | ||
}} | ||
</WithTheme> | ||
) | ||
} | ||
} | ||
export default AgreeItem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,101 +1,181 @@ | ||
import React from 'react' | ||
import classNames from 'classnames' | ||
import useMergedState from 'rc-util/lib/hooks/useMergedState' | ||
import * as React from 'react' | ||
import { | ||
Animated, | ||
Easing, | ||
Platform, | ||
Pressable, | ||
StyleProp, | ||
Text, | ||
TextStyle, | ||
TouchableWithoutFeedback, | ||
TouchableNativeFeedback, | ||
View, | ||
ViewStyle, | ||
} from 'react-native' | ||
import Icon from '../icon' | ||
import { WithTheme, WithThemeStyles } from '../style' | ||
import AntmView from '../view/index' | ||
import devWarning from '../_util/devWarning' | ||
import { useAnimatedTiming } from '../_util/hooks/useAnimations' | ||
import { CheckboxPropsType } from './PropsType' | ||
import CheckboxStyles, { CheckboxStyle } from './style/index' | ||
|
||
export interface CheckboxProps | ||
extends CheckboxPropsType, | ||
WithThemeStyles<CheckboxStyle> { | ||
style?: StyleProp<TextStyle> | ||
style?: StyleProp<ViewStyle> | ||
} | ||
//TODO: ref interface | ||
export interface RefCheckboxProps { | ||
onPress: () => void | ||
} | ||
|
||
export default class Checkbox extends React.Component<CheckboxProps, any> { | ||
static CheckboxItem: any | ||
static AgreeItem: any | ||
const InternalCheckbox = ( | ||
{ | ||
prefixCls = 'checkbox', | ||
style, | ||
styles, | ||
children, | ||
defaultChecked, | ||
disabled, | ||
onChange, | ||
indeterminate, | ||
...restProps | ||
}: CheckboxProps, | ||
ref: React.Ref<any>, | ||
) => { | ||
devWarning( | ||
'checked' in restProps || !('value' in restProps), | ||
'Checkbox', | ||
'`value` is not a valid prop, do you mean `checked`?', | ||
) | ||
|
||
constructor(props: CheckboxProps, context: any) { | ||
super(props, context) | ||
const [innerChecked, setInnerChecked] = useMergedState<boolean>(false, { | ||
value: restProps.checked, | ||
defaultValue: defaultChecked, | ||
}) | ||
|
||
this.state = { | ||
checked: props.checked || props.defaultChecked || false, | ||
} | ||
const [animatedValue, animate] = useAnimatedTiming() | ||
const transitionOpacity = { | ||
opacity: animatedValue.interpolate({ | ||
inputRange: [0, 1], | ||
outputRange: [0, 1], | ||
}), | ||
} | ||
const transitionTransform = { | ||
transform: [ | ||
{ rotate: '45deg' }, | ||
{ | ||
scale: animatedValue.interpolate({ | ||
inputRange: [0, 1], | ||
outputRange: [0, 1], | ||
}), | ||
}, | ||
], | ||
} | ||
|
||
UNSAFE_componentWillReceiveProps(nextProps: CheckboxProps): void { | ||
if (typeof nextProps.checked === 'boolean') { | ||
this.setState({ | ||
checked: !!nextProps.checked, | ||
//initial animate or receive props | ||
React.useEffect(() => { | ||
animate({ | ||
toValue: innerChecked ? 1 : 0, | ||
duration: 300, | ||
easing: Easing.bezier(0.68, -0.55, 0.27, 1.55), | ||
}) | ||
}, [animate, innerChecked]) | ||
|
||
function triggerChange(newChecked: boolean) { | ||
let mergedChecked = innerChecked | ||
|
||
if (!disabled) { | ||
mergedChecked = newChecked | ||
!('checked' in restProps) && setInnerChecked(mergedChecked) | ||
onChange?.({ | ||
target: { | ||
checked: mergedChecked, | ||
}, | ||
}) | ||
} | ||
|
||
return mergedChecked | ||
} | ||
const onInternalClick = () => { | ||
triggerChange(!innerChecked) | ||
} | ||
|
||
handleClick = () => { | ||
if (this.props.disabled) { | ||
return | ||
} | ||
const checked = !this.state.checked | ||
if (!(typeof this.props.checked === 'boolean')) { | ||
this.setState({ | ||
checked, | ||
}) | ||
class Checkbox extends React.Component { | ||
onPress = () => { | ||
onInternalClick() | ||
} | ||
if (this.props.onChange) { | ||
this.props.onChange({ target: { checked } }) | ||
} | ||
} | ||
render() { | ||
return ( | ||
<WithTheme themeStyles={CheckboxStyles} styles={styles}> | ||
{(_styles) => { | ||
const antd_checkbox = classNames(`${prefixCls}`, { | ||
[`${prefixCls}_checked`]: innerChecked, | ||
[`${prefixCls}_disabled`]: disabled, | ||
}) | ||
.split(' ') | ||
.map((a) => _styles[a]) | ||
|
||
render() { | ||
const { style, disabled, children } = this.props | ||
const checked = this.state.checked | ||
return ( | ||
<WithTheme themeStyles={CheckboxStyles} styles={this.props.styles}> | ||
{(styles, theme) => { | ||
let icon | ||
if (checked) { | ||
icon = disabled ? ( | ||
<Icon name="check-square" style={[styles.icon, style]} /> | ||
) : ( | ||
<Icon | ||
name="check-square" | ||
color={theme.brand_primary} | ||
style={[styles.icon, style]} | ||
/> | ||
) | ||
} else { | ||
icon = disabled ? ( | ||
<Icon name="border" style={[styles.icon, style]} /> | ||
) : ( | ||
<Icon | ||
name="border" | ||
color={theme.brand_primary} | ||
style={[styles.icon, style]} | ||
/> | ||
) | ||
} | ||
|
||
return ( | ||
<TouchableWithoutFeedback onPress={this.handleClick}> | ||
<View style={[styles.wrapper]}> | ||
{icon} | ||
{typeof children === 'string' ? ( | ||
// tslint:disable-next-line:jsx-no-multiline-js | ||
<Text style={styles.iconRight}>{this.props.children}</Text> | ||
) : ( | ||
children | ||
)} | ||
const antd_checkbox_inner = classNames(`${prefixCls}_inner`, { | ||
[`${prefixCls}_inner_indeterminate`]: indeterminate, | ||
[`${prefixCls}_inner_disabled`]: disabled, | ||
}) | ||
.split(' ') | ||
.map((a) => _styles[a]) | ||
|
||
const antd_checkbox_inner_after = classNames(undefined, { | ||
[`${prefixCls}_inner_after`]: !indeterminate, | ||
[`${prefixCls}_inner_after_indeterminate`]: indeterminate, | ||
[`${prefixCls}_inner_after_disabled`]: disabled, | ||
}) | ||
.split(' ') | ||
.map((a) => _styles[a]) | ||
|
||
const antd_checlbox_label = classNames(`${prefixCls}_label`, { | ||
[`${prefixCls}_label_disabled`]: disabled, | ||
}) | ||
.split(' ') | ||
.map((a) => _styles[a]) | ||
|
||
const Color = innerChecked | ||
? _styles.checkbox_checked?.borderColor | ||
: _styles.checkbox?.borderColor | ||
return ( | ||
<View style={[_styles[`${prefixCls}_wrapper`], style]}> | ||
<View style={_styles.checkbox_wave}> | ||
This comment has been minimized.
Sorry, something went wrong. |
||
<TouchableNativeFeedback | ||
background={ | ||
Platform.Version >= 21 | ||
? TouchableNativeFeedback.Ripple(Color || '', true, 13) | ||
: TouchableNativeFeedback.SelectableBackground() | ||
} | ||
useForeground={true} | ||
disabled={disabled} | ||
onPress={this.onPress}> | ||
<View style={antd_checkbox}> | ||
<Animated.View | ||
style={[antd_checkbox_inner, transitionOpacity]} | ||
/> | ||
<Animated.View | ||
style={[transitionTransform, antd_checkbox_inner_after]} | ||
/> | ||
</View> | ||
</TouchableNativeFeedback> | ||
</View> | ||
<Pressable disabled={disabled} onPress={this.onPress}> | ||
<AntmView style={antd_checlbox_label}>{children}</AntmView> | ||
</Pressable> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
) | ||
}} | ||
</WithTheme> | ||
) | ||
) | ||
}} | ||
</WithTheme> | ||
) | ||
} | ||
} | ||
|
||
return <Checkbox ref={ref} {...restProps} /> | ||
} | ||
|
||
const AntmCheckbox = React.forwardRef(InternalCheckbox) | ||
AntmCheckbox.displayName = 'AntmCheckbox' | ||
|
||
export default AntmCheckbox |
Oops, something went wrong.
Use
checkbox_wave
to replaceIcon
So if you want to change icon style, you can rewrite
styles.checkbox_wave
: