@td-design/react-native
Version:
react-native UI组件库
177 lines (175 loc) • 4.93 kB
JavaScript
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useMemo } from 'react';
import { StyleSheet } from 'react-native';
import Svg, { Path } from 'react-native-svg';
import { backgroundColor, border, color, createRestyleComponent, layout, typography, useTheme } from '@shopify/restyle';
import Box from '../box';
import helpers from '../helpers';
import Pressable from '../pressable';
import SvgIcon from '../svg-icon';
import Text from '../text';
import useTag from './useTag';
const BaseTag = createRestyleComponent([border, backgroundColor, color, layout, typography]);
const {
px,
ONE_PIXEL
} = helpers;
const Tag = _ref => {
let {
text,
size = 'middle',
ghost = false,
closable = false,
selectable = true,
activeOpacity = 0.6,
disabled = false,
selected = false,
onClose,
onSelect,
...restProps
} = _ref;
const theme = useTheme();
const {
handleDelete,
handlePress,
checked,
closed
} = useTag({
selected,
disabled,
selectable,
onClose,
onSelect
});
if (closed) return null;
const {
fontFamily,
fontSize = px(12),
fontStyle,
fontWeight,
letterSpacing,
lineHeight,
textAlign,
textDecorationLine,
textDecorationStyle,
textTransform,
color = disabled ? 'disabled' : 'primary100',
backgroundColor,
borderWidth = ONE_PIXEL,
justifyContent = 'center',
alignItems = 'center',
borderRadius = 'x1',
...rest
} = restProps;
let borderColor = rest.borderColor ?? color;
if (ghost && disabled) {
borderColor = 'disabled';
} else if (checked) {
borderColor = 'primary200';
}
const {
paddingHorizontal,
paddingVertical
} = getBySize(size);
const styles = StyleSheet.create({
iconBtn: {
position: 'absolute',
width: px(8),
height: px(8),
top: -px(4),
right: -px(4),
justifyContent: 'center',
alignItems: 'center'
},
iconWrap: {
backgroundColor: theme.colors.icon,
borderRadius: px(8)
},
check: {
position: 'absolute',
bottom: 0,
right: 0
}
});
/** 删除的图标组件 */
const ClosableIcon = useMemo(() => {
if (closable && !disabled) return /*#__PURE__*/React.createElement(Pressable, {
activeOpacity: 1,
hitOffset: 5,
onPress: handleDelete,
style: styles.iconBtn
}, /*#__PURE__*/React.createElement(Box, {
style: styles.iconWrap
}, /*#__PURE__*/React.createElement(SvgIcon, {
name: "close",
color: theme.colors.white,
size: px(10)
})));
return null;
}, [closable, disabled, styles.iconBtn, styles.iconWrap, theme.colors.white]);
/** 选中的图标组件 */
const CheckedIcon = useMemo(() => {
if (checked) return /*#__PURE__*/React.createElement(Box, {
style: styles.check
}, /*#__PURE__*/React.createElement(Svg, {
viewBox: "0 0 1040 1024",
width: px(28),
height: px(28)
}, /*#__PURE__*/React.createElement(Path, {
d: "M1023.83 474.655l-549.255 549.283h549.255V474.655zM783.16 979.732l-96.896-96.933 36.335-36.35 60.56 60.583L952.729 737.4l36.335 36.35L783.16 979.731z",
fill: theme.colors.primary200
})));
return null;
}, [checked, styles.check, theme.colors.primary200]);
const Content = /*#__PURE__*/React.createElement(BaseTag, _extends({}, rest, {
justifyContent,
alignItems,
borderColor,
borderWidth,
borderRadius,
paddingVertical,
paddingHorizontal,
backgroundColor: ghost ? 'transparent' : backgroundColor
}), /*#__PURE__*/React.createElement(Text, {
fontFamily,
fontSize,
fontStyle,
fontWeight,
letterSpacing,
lineHeight,
textAlign,
textDecorationLine,
textDecorationStyle,
textTransform,
color
}, text));
if (selectable) return /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(Pressable, {
disabled: disabled,
activeOpacity: activeOpacity,
onPress: handlePress
}, Content), ClosableIcon, CheckedIcon);
return /*#__PURE__*/React.createElement(Box, null, Content, ClosableIcon, CheckedIcon);
};
Tag.displayName = 'Tag';
export default Tag;
function getBySize(size) {
switch (size) {
case 'large':
return {
paddingHorizontal: px(16),
paddingVertical: px(8)
};
case 'middle':
default:
return {
paddingHorizontal: px(12),
paddingVertical: px(6)
};
case 'small':
return {
paddingHorizontal: px(4),
paddingVertical: px(4)
};
}
}
//# sourceMappingURL=index.js.map