UNPKG

tuya-panel-kit

Version:

a functional component library for developing tuya device panels!

244 lines (234 loc) 6.42 kB
import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { Text, ColorPropType, ViewPropTypes } from 'react-native'; import Slider from '../../slider'; import svgs from '../../iconfont/svg/defaultSvg'; import svgsART from '../../iconfont/art/defaultSvg'; import { CoreUtils, ThemeUtils } from '../../../utils'; import { StyledPlaceholder } from './styled'; import { StyledItem, StyledItemContent, StyledValueText, StyledImage, StyledIconFont, } from '../styled'; const { isNil } = CoreUtils; const { parseToStyle } = ThemeUtils; export default class SliderItem extends Component { static propTypes = { ...Slider.propTypes, /** * 主题 */ theme: PropTypes.shape({ iconColor: ColorPropType, descFontColor: ColorPropType, cellBg: ColorPropType, cellRadius: PropTypes.number, margin: PropTypes.array, padding: PropTypes.array, // 支持所有Slider的主题变量 }), /** * 左侧 Icon 类型,默认为 `auto`,根据传递进来的 `Icon` 类型自动判断, */ iconType: PropTypes.oneOf(['auto', 'image', 'iconfont', 'text']), /** * 右侧 Action 类型,默认为 `auto`,根据传递进来的 `Action` 类型自动判断, */ actionType: PropTypes.oneOf(['auto', 'image', 'iconfont', 'text']), /** * 左侧 Icon 具体值,当类型为 `string`时,默认使用 `IconFont`, */ Icon: PropTypes.oneOfType([ PropTypes.element, PropTypes.func, PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object, ]), /** * 右侧 Action 具体值,当类型为 `string`时,默认使用 `TYText` */ Action: PropTypes.oneOfType([ PropTypes.element, PropTypes.func, PropTypes.string, PropTypes.number, PropTypes.bool, PropTypes.object, ]), /** * 左侧图标栏尺寸 */ iconSize: PropTypes.number, /** * 左侧图标栏尺寸颜色 */ iconColor: ColorPropType, /** * 列表样式 */ style: ViewPropTypes.style, /** * 内容样式 */ contentStyle: ViewPropTypes.style, /** * 字体样式 */ textStyle: Text.propTypes.style, /** * 滑动条样式 */ sliderStyle: ViewPropTypes.style, /** * 图片的tintColor是否跟随iconColor,默认为`true`, * 可用于某些图片不需要改变底色的场景 */ imageFollowIconColor: PropTypes.bool, /** * 是否使用 ART 实现版本 */ useART: PropTypes.bool, }; static defaultProps = { theme: {}, iconType: 'auto', actionType: 'auto', Icon: null, Action: null, iconSize: 17, iconColor: null, style: null, contentStyle: null, textStyle: null, sliderStyle: null, imageFollowIconColor: true, useART: false, }; getImageComponent(source) { const { theme, imageFollowIconColor, iconSize, iconColor } = this.props; return ( <StyledImage size={iconSize} iconColor={iconColor || theme.iconColor} source={source} imageFollowIconColor={imageFollowIconColor} /> ); } getIconComponent(data) { const { theme, iconSize, iconColor, useART } = this.props; const svgMap = useART ? svgsART : svgs; return ( <StyledIconFont size={iconSize} name={svgMap[data] ? data : undefined} // name 为undefined则会使用d d={data} color={iconColor || theme.iconColor} useART={useART} /> ); } getTextComponent(text) { const { theme, textStyle } = this.props; return ( <StyledValueText style={[theme.descFontColor && { color: theme.descFontColor }, textStyle]}> {text} </StyledValueText> ); } renderItem = isLeft => { const value = isLeft ? this.props.Icon : this.props.Action; const type = isLeft ? this.props.iconType : this.props.actionType; if (React.isValidElement(value)) { return value; } let itemComponent; if (type !== 'auto') { switch (type) { case 'image': itemComponent = this.getImageComponent(value); break; case 'iconfont': itemComponent = this.getIconComponent(value); break; case 'text': default: itemComponent = this.getTextComponent(value); break; } return ( itemComponent && <StyledPlaceholder alignLeft={isLeft}>{itemComponent}</StyledPlaceholder> ); } switch (typeof value) { case 'function': itemComponent = value(); break; case 'string': itemComponent = isLeft ? this.getIconComponent(value) : this.getTextComponent(value); break; case 'number': itemComponent = this.getImageComponent(value); break; case 'object': { if (value && value.uri) { itemComponent = this.getImageComponent(value); } else { itemComponent = value; } break; } default: itemComponent = null; break; } return ( itemComponent && <StyledPlaceholder alignLeft={isLeft}>{itemComponent}</StyledPlaceholder> ); }; renderSlider = () => { const { style, iconType, Icon, actionType, Action, iconSize, iconColor, textStyle, sliderStyle, ...sliderProps } = this.props; return <Slider style={[{ flex: 1, alignSelf: 'stretch' }, sliderStyle]} {...sliderProps} />; }; render() { const { theme, style, contentStyle } = this.props; // cellRadius can be 0 const radiusStyle = !isNil(theme.cellRadius) && { borderRadius: theme.cellRadius }; const itemStyle = [ radiusStyle, theme.margin && parseToStyle(theme.margin, 'margin'), theme.cellBg && { backgroundColor: theme.cellBg }, style, ]; const itemContentStyle = [ radiusStyle, theme.padding && parseToStyle(theme.padding, 'padding'), contentStyle, ]; return ( <StyledItem style={itemStyle} disabled={true}> <StyledItemContent style={itemContentStyle}> {this.renderItem(true)} {this.renderSlider()} {this.renderItem(false)} </StyledItemContent> </StyledItem> ); } }