react-native#TextStyle TypeScript Examples
The following examples show how to use
react-native#TextStyle.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utilities.ts From react-native-jigsaw with MIT License | 7 votes |
export function extractStyles(style: StyleProp<any>) {
const {
color,
fontFamily,
fontWeight,
fontSize,
lineHeight,
letterSpacing,
textTransform,
textAlign,
textDecorationLine,
textDecorationColor,
textDecorationStyle,
...viewStyles
} = StyleSheet.flatten(style || {});
const textStyles: TextStyle = {
color,
fontFamily,
fontWeight,
fontSize,
lineHeight,
letterSpacing,
textTransform,
textAlign,
textDecorationLine,
textDecorationColor,
textDecorationStyle,
};
return { viewStyles, textStyles };
}
Example #2
Source File: CheckboxRow.tsx From react-native-jigsaw with MIT License | 6 votes |
renderLabel = (
value: string | React.ReactNode,
labelStyle: StyleProp<TextStyle>,
textStyle: StyleProp<TextStyle>
) => {
if (isString(value)) {
return <Text style={[textStyle, labelStyle]}>{value}</Text>;
} else {
return <>{value}</>;
}
}
Example #3
Source File: Text.tsx From sellflow with MIT License | 6 votes |
function resolveTextStyle(
fonts: ReactNativePaper.ThemeFonts,
fontWeight: 'bold' | 'medium' | 'normal',
fontStyle: 'normal' | 'italic',
): TextStyle | undefined {
let useItalicPreset = fontStyle === 'italic';
let fontFamily = useItalicPreset
? fonts.italic.fontFamily
: fonts.regular.fontFamily;
switch (fontWeight) {
case 'bold':
fontFamily = fonts.bold?.fontFamily;
break;
case 'medium':
fontFamily = fonts.medium.fontFamily;
break;
}
return {
fontFamily,
};
}
Example #4
Source File: Avatar.tsx From sellflow with MIT License | 6 votes |
export default function Avatar(props: Props) {
let { firstName, lastName, size, containerStyle } = props;
let avatarSize: StyleProp<ViewStyle> = {
width: size,
height: size,
borderRadius: Math.round(size / 2),
};
let textSize: StyleProp<TextStyle> = {
fontSize: Math.round(size / 2),
};
return (
<View style={[styles.avatar, containerStyle, avatarSize]}>
<Text
style={[styles.nameInitial, textSize]}
>{`${firstName[0]}${lastName[0]}`}</Text>
</View>
);
}
Example #5
Source File: ExternalLink.tsx From selftrace with MIT License | 6 votes |
export default function ExternalLink({
isColored = true,
href,
target = 'blank',
children,
style,
}: Props) {
const linkStyles: [TextStyle] = [isColored ? styles.bright : styles.plain];
return (
<A href={href} target={target} style={[linkStyles, style]}>
<Text>{children}</Text>
</A>
);
}
Example #6
Source File: RadioButtonRow.tsx From react-native-jigsaw with MIT License | 6 votes |
renderLabel = (
value: string | React.ReactNode,
labelStyle: StyleProp<TextStyle>,
textStyle: StyleProp<TextStyle>
) => {
if (typeof value === "string") {
return <Text style={[labelStyle, textStyle]}>{value}</Text>;
} else {
return <>{value}</>;
}
}
Example #7
Source File: index.tsx From react-native-floating-label-input with MIT License | 6 votes |
setGlobalStyles: SetGlobalStyles = {
/**Set global styles to all floating-label-inputs container */
containerStyles: undefined as ViewStyle | undefined,
/**Set global custom styles to all floating-label-inputs labels */
customLabelStyles: undefined as CustomLabelProps | undefined,
/**Set global styles to all floating-label-inputs input */
inputStyles: undefined as TextStyle | undefined,
/**Set global styles to all floating-label-inputs label */
labelStyles: undefined as TextStyle | undefined,
/**Set global styles to all floating-label-inputs show password container */
showPasswordContainerStyles: undefined as ViewStyle | undefined,
/**Set global styles to all floating-label-inputs show password image */
showPasswordImageStyles: undefined as ImageStyle | undefined,
/**Set global style to the countdown text */
showCountdownStyles: undefined as TextStyle | undefined,
}
Example #8
Source File: CheckboxGroupRow.tsx From react-native-jigsaw with MIT License | 6 votes |
renderLabel = (
value: string | React.ReactNode,
labelStyle: StyleProp<TextStyle>,
textStyle: StyleProp<TextStyle>
) => {
if (typeof value === "string") {
return <Text style={[labelStyle, textStyle]}>{value}</Text>;
} else {
return <>{value}</>;
}
}
Example #9
Source File: utils.ts From react-native-controlled-mentions with MIT License | 6 votes |
defaultMentionTextStyle: StyleProp<TextStyle> = {fontWeight: 'bold', color: 'blue'}
Example #10
Source File: ButtonSelect.tsx From mobile with Apache License 2.0 | 5 votes |
ButtonSelect = ({
text,
onPress,
variant,
color: buttonColorName,
disabled,
iconName,
testID,
}: ButtonSelectProps) => {
const theme = useTheme<Theme>();
const variantProps = theme.buttonVariants[variant];
const disabledProps = disabled ? variantProps.disabled || {} : {};
const themedStyles = {...variantProps, ...disabledProps};
const {fontSize, fontWeight, fontFamily} = (themedStyles as unknown) as TextStyle & ViewStyle;
const textColor = themedStyles.textColor;
const buttonColor = buttonColorName && theme.colors[buttonColorName];
const borderColorName = (themedStyles.color as keyof Theme['colors']) || 'bodyText';
const onPressHandler = onPress;
const borderRadius = 5;
const content = (
<Box
borderColor={borderColorName}
borderWidth={2}
borderRadius={borderRadius}
alignItems="center"
justifyContent="flex-start"
shadowColor="bodyText"
paddingHorizontal="m"
paddingVertical="m"
flexDirection="row"
marginBottom="m"
>
<Text style={{...styles.content, color: textColor || buttonColor, fontWeight, fontFamily, fontSize}}>{text}</Text>
<Box style={{...styles.iconOffset}}>{iconName && <Icon size={12} name={iconName} />}</Box>
</Box>
);
const accessibilityProps = {
accessibilityRole: 'button' as 'button',
accessibilityState: {disabled},
};
return (
<TouchableOpacity
activeOpacity={0.8}
onPress={onPressHandler}
style={styles.stretch}
disabled={disabled}
testID={testID}
{...accessibilityProps}
>
{content}
</TouchableOpacity>
);
}
Example #11
Source File: Button.tsx From sellflow with MIT License | 5 votes |
function useButtonStyle(options: Options) {
let { preset, disabled, buttonColor } = options;
let { colors, roundness } = useTheme();
let elevation = 0;
let textColor = colors.text;
let backgroundColor = 'transparent';
let borderColor = 'transparent';
let borderWidth = 0;
if (preset === 'primary') {
elevation = 2;
backgroundColor = disabled
? color(colors.primary)
.alpha(0.12)
.rgb()
.string()
: !!buttonColor
? buttonColor
: colors.primary;
} else if (preset === 'secondary') {
borderColor = disabled
? color(colors.primary)
.alpha(0.4)
.rgb()
.string()
: colors.primary;
borderWidth = 2;
}
let isBackgroundDark =
backgroundColor === 'transparent' ? false : color(backgroundColor).isDark();
if (disabled) {
textColor = color(isBackgroundDark ? 'white' : colors.primary)
.alpha(0.4)
.rgb()
.string();
} else if (preset === 'primary') {
textColor = isBackgroundDark ? 'white' : 'black';
} else if (buttonColor) {
textColor = buttonColor;
} else {
textColor = colors.primary;
}
let textStyle = { color: textColor } as TextStyle;
let buttonStyle = {
backgroundColor,
borderColor,
borderWidth,
borderRadius: roundness,
elevation: disabled ? 0 : elevation,
} as ViewStyle;
let noShadowStyle = {
shadowOffset: { width: 0, height: 0 },
shadowColor: 'transparent',
} as ViewStyle;
return { textStyle, buttonStyle, noShadowStyle, textColor };
}
Example #12
Source File: Button.tsx From mobile with Apache License 2.0 | 5 votes |
Button = ({
text,
onPress,
variant,
color: buttonColorName,
disabled,
loading,
externalLink,
}: ButtonProps) => {
const [i18n] = useI18n();
const theme = useTheme<Theme>();
const variantProps = theme.buttonVariants[variant];
const disabledProps = disabled ? variantProps.disabled || {} : {};
const themedStyles = {...variantProps, ...disabledProps};
const {fontSize, fontWeight, fontFamily, color, borderWidth, height} = (themedStyles as unknown) as TextStyle &
ViewStyle;
const textColor = themedStyles.textColor;
const buttonColor = buttonColorName && theme.colors[buttonColorName];
const onPressHandler = loading ? () => {} : onPress;
const externalLinkProps = externalLink
? {
accessibilityLabel: text,
accessibilityHint: i18n.translate('Home.ExternalLinkHint'),
accessibilityRole: 'link' as AccessibilityRole,
}
: {};
const externalArrowIcon = textColor === palette.white ? 'icon-external-arrow-light' : 'icon-external-arrow';
const content = (
<Box
borderRadius={4}
alignItems="center"
justifyContent="center"
style={{backgroundColor: color, minHeight: height, borderWidth, borderColor: buttonColor}}
paddingHorizontal="m"
flexDirection="row"
>
{loading ? (
<ActivityIndicator color={textColor} size="large" />
) : (
<>
<Text style={{...styles.content, color: textColor || buttonColor, fontWeight, fontFamily, fontSize}}>
{text}
</Text>
{externalLink && <Icon name={externalArrowIcon} />}
</>
)}
</Box>
);
const accessibilityProps = {
accessibilityRole: 'button' as 'button',
accessibilityState: {disabled},
...externalLinkProps,
};
if (Platform.OS === 'android') {
return (
<Ripple rippleContainerBorderRadius={4} onPress={onPressHandler} {...accessibilityProps}>
{content}
</Ripple>
);
}
return (
<TouchableOpacity onPress={onPressHandler} style={styles.stretch} disabled={disabled} {...accessibilityProps}>
{content}
</TouchableOpacity>
);
}
Example #13
Source File: Button.tsx From react-native-jigsaw with MIT License | 5 votes |
function Base({
Icon,
icon,
title,
onPress,
loading,
disabled,
style,
...props
}: BaseProps): JSX.Element {
const {
color,
fontFamily,
fontWeight,
fontSize,
lineHeight,
letterSpacing,
textTransform,
textAlign,
textDecorationLine,
textDecorationColor,
textDecorationStyle,
...buttonStyles
} = StyleSheet.flatten(style || ({} as TextStyle));
const titleStyles: TextStyle = {
color,
fontFamily,
fontWeight,
fontSize,
lineHeight,
letterSpacing,
textTransform,
textAlign,
textDecorationLine,
textDecorationColor,
textDecorationStyle,
};
if (textAlign === "left") {
buttonStyles.justifyContent = "flex-start";
}
if (textAlign === "right") {
buttonStyles.justifyContent = "flex-end";
}
return (
<Pressable
onPress={onPress}
disabled={disabled || loading}
style={({ pressed }) => {
return [
styles.base,
{
opacity: pressed || disabled ? 0.75 : 1,
},
buttonStyles,
];
}}
{...props}
>
{loading ? (
<ActivityIndicator size="small" color={color} style={styles.loading} />
) : null}
{icon && !loading ? (
<Icon
name={icon}
color={color as string}
style={styles.icon}
size={CONSTANTS.icon}
/>
) : null}
<Text style={titleStyles}>{title}</Text>
</Pressable>
);
}
Example #14
Source File: theme.tsx From sellflow with MIT License | 5 votes |
textInputLabel: StyleProp<TextStyle> = { fontSize: FONT_SIZE.small, }
Example #15
Source File: theme.tsx From sellflow with MIT License | 5 votes |
defaultButtonLabel: StyleProp<TextStyle> = { fontSize: FONT_SIZE.medium, fontFamily: FONT_FAMILY.MEDIUM, }
Example #16
Source File: utils.tsx From lowkey-react-native-mentions-input with MIT License | 5 votes |
parseMarkdown = (
text: string,
mentionStyle: TextStyle,
urlStyle?: TextStyle,
handleURL?: (url: string) => void
) => {
let textToParse = text;
let parsedTextArray: Array<React.ReactNode> = [];
let parseHeadIndex = 0;
let matches = [...matchAll(text, PATTERNS.MENTION)];
if (matches.length === 0) {
let currentParsable = decodeURIComponentSafely(textToParse);
let matchesURL = [...matchAll(currentParsable, PATTERNS.URL)];
if (matchesURL.length > 0) {
parsedTextArray.push(
<Text key={getKeyComponent()}>
{currentParsable.substring(0, matchesURL[0].index)}
</Text>
);
matchesURL.map((url, index) => {
let urlIndex = 0;
if (typeof url.index !== 'undefined') {
urlIndex = url.index;
}
parsedTextArray.push(
<TouchableWithoutFeedback
key={getKeyComponent()}
onPress={() => (handleURL ? handleURL(url[0]) : null)}
>
<Text style={urlStyle}>
{currentParsable.substring(urlIndex, url[0].length + urlIndex)}
</Text>
</TouchableWithoutFeedback>
);
parsedTextArray.push(
<Text key={getKeyComponent()}>
{currentParsable.substring(
url[0].length +
(typeof url.index !== 'undefined' ? url.index : 0),
index === matchesURL.length - 1
? currentParsable.length
: matchesURL[index + 1].index
)}
</Text>
);
});
} else {
return <Text>{decodeURIComponentSafely(textToParse)}</Text>;
}
return parsedTextArray;
}
matches.map((match, index) => {
const matchedUser = match[0].slice(2, -1);
const mention = {
id: matchedUser.split('::')[1],
name: matchedUser.split('::')[0],
};
let currentParsable = decodeURIComponentSafely(
textToParse.substring(parseHeadIndex, match.index)
);
let matchesURL = [...matchAll(currentParsable, PATTERNS.URL)];
if (matchesURL.length > 0) {
parsedTextArray.push(
<Text key={getKeyComponent()}>
{currentParsable.substring(0, matchesURL[0].index)}
</Text>
);
matchesURL.map((url, index) => {
let urlIndex = 0;
if (typeof url.index !== 'undefined') {
urlIndex = url.index;
}
parsedTextArray.push(
<TouchableWithoutFeedback
key={getKeyComponent()}
onPress={() => (handleURL ? handleURL(url[0]) : null)}
>
<Text style={urlStyle}>
{currentParsable.substring(urlIndex, url[0].length + urlIndex)}
</Text>
</TouchableWithoutFeedback>
);
parsedTextArray.push(
<Text key={getKeyComponent()}>
{currentParsable.substring(
url[0].length + urlIndex,
index === matchesURL.length - 1
? currentParsable.length
: matchesURL[index + 1].index
)}
</Text>
);
});
} else {
parsedTextArray.push(
<Text key={getKeyComponent()}>
{decodeURIComponentSafely(
textToParse.substring(parseHeadIndex, match.index)
)}
</Text>
);
}
parsedTextArray.push(
<TouchableWithoutFeedback
onPress={() => (handleURL ? handleURL(mention.id) : null)}
>
<Text style={mentionStyle} key={getKeyComponent()}>{`@${decodeURI(
mention.name
)}`}</Text>
</TouchableWithoutFeedback>
);
if (typeof match.index === 'number') {
parseHeadIndex = match.index + match[0].length;
}
if (index === matches.length - 1) {
let lastParsable = decodeURIComponentSafely(
textToParse.substring(parseHeadIndex, textToParse.length)
);
let matchesURL = [...matchAll(lastParsable, PATTERNS.URL)];
if (matchesURL.length > 0) {
parsedTextArray.push(
<Text key={getKeyComponent()}>
{lastParsable.substring(0, matchesURL[0].index)}
</Text>
);
matchesURL.map((url, index) => {
let urlIndex = 0;
if (typeof url.index !== 'undefined') {
urlIndex = url.index;
}
parsedTextArray.push(
<TouchableWithoutFeedback
key={getKeyComponent()}
onPress={() => (handleURL ? handleURL(url[0]) : null)}
>
<Text style={urlStyle}>
{lastParsable.substring(urlIndex, url[0].length + urlIndex)}
</Text>
</TouchableWithoutFeedback>
);
parsedTextArray.push(
<Text key={getKeyComponent()}>
{lastParsable.substring(
url[0].length + urlIndex,
index === matchesURL.length - 1
? lastParsable.length
: matchesURL[index + 1].index
)}
</Text>
);
});
} else {
parsedTextArray.push(
<Text key={getKeyComponent()}>
{decodeURIComponentSafely(
textToParse.substring(parseHeadIndex, textToParse.length)
)}
</Text>
);
}
}
});
return parsedTextArray;
}
Example #17
Source File: fonts.ts From lexicon with MIT License | 5 votes |
FONT_VARIANTS = {
normal: { fontWeight: '400' } as TextStyle,
semiBold: { fontWeight: '600' } as TextStyle,
bold: { fontWeight: '700' } as TextStyle,
}
Example #18
Source File: styles.ts From iotc-cpm-sample with MIT License | 5 votes |
DefaultStyles: {
header: TextStyle;
centerFragment: ViewStyle;
centeredButton: ViewStyle;
elevated: ViewStyle;
itemName: TextStyle;
itemDetail: TextStyle;
} = {
header: {
fontWeight: 'bold',
fontSize: 24,
},
centerFragment: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
centeredButton: {
width: 230,
height: 50,
marginVertical: 20,
justifyContent: 'center',
},
elevated: {
...Platform.select({
ios: {
shadowColor: "'rgba(0, 0, 0, 0.14)'",
shadowOffset: {
width: 0,
height: 3,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
android: {
elevation: 2,
},
}),
},
itemName: {
fontWeight: 'bold',
fontSize: 16,
},
itemDetail: {
fontSize: 14,
},
}
Example #19
Source File: typography.ts From selftrace with MIT License | 5 votes |
INACTIVE_TEXT_STYLES: TextStyle = {
fontWeight: '600',
color: Colors.INACTIVE_TEXT.toString(),
}
Example #20
Source File: ProgressBarCircle.tsx From companion-kit with MIT License | 5 votes |
export function ProgressBarCircleGradient(this: never, props: PropsGradient) {
const { animationStep, title, diameter, gradient, progress, style, titleStyle, startFromBottom } = props;
const length = Math.round(diameter * Math.PI);
const [ offset ] = React.useState(() => {
const startProgress = progress - (animationStep || 0.1);
return new Animated.Value(getOffset(diameter, startProgress));
});
React.useEffect(() => {
Animated.timing(offset, {
toValue: getOffset(diameter, progress),
duration: 2000,
delay: 750,
}).start();
}, [progress]);
const boxSize = diameter + 6;
const origin = diameter / 2;
const defaultTitleStyles: StyleProp<TextStyle> = {
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
};
return (
<View style={style}>
<Text style={[TextStyles.p3, defaultTitleStyles, titleStyle]}>{title}</Text>
<Svg id="progress-bar-circle" width="100%" height="100%" viewBox={`0 0 ${boxSize} ${boxSize}`} fill="none">
<G x={3} y={3}>
<Circle
id="circle-bg"
opacity="0.2"
cx={diameter / 2}
cy={diameter / 2}
r={diameter / 2}
strokeWidth="3"
stroke="url(#paint0_linear)"
fill="none"
/>
<AnimatedContainer
id="circle-progress"
fill="none"
cx={diameter / 2}
cy={diameter / 2}
r={diameter / 2}
strokeWidth="3"
stroke="url(#paint0_linear)"
strokeDasharray={length}
strokeDashoffset={offset}
origin={`${origin}, ${origin}`}
rotation={startFromBottom ? 90 : -90}
/>
</G>
<Defs>
{gradient ? (
<LinearGradient id="paint0_linear" x1={diameter / 2} y1={diameter} x2={diameter} y2={0} gradientUnits="userSpaceOnUse">
{gradient.map((color, i) => {
// tslint:disable-next-line: no-unused-expression
return <Stop key={`${color.title}_${i}`} offset={color.offset} stopColor={color.title}/>;
})}
</LinearGradient>
) : (
<LinearGradient id="paint0_linear" x1={0} y1={diameter / 2} x2={diameter} y2={diameter / 2} gradientUnits="userSpaceOnUse">
<Stop offset="0.0996095" stopColor="#FFCECF"/>
<Stop offset="0.238673" stopColor="#9A87E7"/>
<Stop offset="0.384948" stopColor="#FFAFD5"/>
<Stop offset="0.512681" stopColor="#FA8989"/>
<Stop offset="0.642474" stopColor="#CFC4FF"/>
<Stop offset="0.776388" stopColor="#FFAFD5"/>
<Stop offset="0.90206" stopColor="#FFCED0"/>
</LinearGradient>
)}
</Defs>
</Svg>
</View>
);
}
Example #21
Source File: index.tsx From react-native-floating-label-input with MIT License | 4 votes |
FloatingLabelInput: React.ForwardRefRenderFunction<InputRef, Props> = (
{
label,
labelProps,
mask,
isPassword,
maxLength,
inputStyles,
showCountdown,
showCountdownStyles,
labelStyles,
darkTheme,
countdownLabel,
currencyDivider,
currency,
maskType,
onChangeText,
customHidePasswordComponent,
customShowPasswordComponent,
isFocused,
onBlur,
onFocus,
onTogglePassword,
togglePassword,
leftComponent,
rightComponent,
customHidePasswordImage,
customLabelStyles = {},
staticLabel = false,
hint,
hintTextColor,
onSubmit,
containerStyles,
customShowPasswordImage,
showPasswordContainerStyles,
maxDecimalPlaces,
multiline,
showPasswordImageStyles,
value = '',
animationDuration,
...rest
}: Props,
ref: any,
) => {
const [halfTop, setHalfTop] = useState(0);
const [isFocusedState, setIsFocused] = useState(false);
const [secureText, setSecureText] = useState(true);
const inputRef = useRef<any>(null);
customLabelStyles = {
fontSizeFocused: 10,
fontSizeBlurred: 14,
colorFocused: '#49658c',
colorBlurred: '#49658c',
...setGlobalStyles?.customLabelStyles,
...customLabelStyles,
};
const [fontColorAnimated] = useState(new Animated.Value(0));
const [fontSizeAnimated] = useState(
new Animated.Value(
isFocused
? customLabelStyles.fontSizeFocused
? customLabelStyles.fontSizeFocused
: 10
: customLabelStyles.fontSizeBlurred
? customLabelStyles.fontSizeBlurred
: 14,
),
);
const [leftAnimated] = useState(
new Animated.Value(
staticLabel
? customLabelStyles?.leftFocused !== undefined
? customLabelStyles.leftFocused
: 15
: customLabelStyles != undefined &&
customLabelStyles.leftBlurred !== undefined
? customLabelStyles.leftBlurred
: 0,
),
);
const [topAnimated] = useState(
new Animated.Value(
staticLabel
? customLabelStyles?.topFocused !== undefined
? customLabelStyles.topFocused
: 0
: customLabelStyles.topBlurred
? customLabelStyles.topBlurred
: 0,
),
);
useEffect(() => {
if (isFocused === undefined) {
if (value !== '' || isFocusedState) {
setIsFocused(true);
} else if (value === '' || value === null) {
setIsFocused(false);
}
}
}, [value]);
useEffect(() => {
if (isFocused !== undefined) {
if (value !== '' || isFocused) {
setIsFocused(true);
} else {
setIsFocused(false);
}
}
}, [isFocused, value]);
useEffect(() => {
if (togglePassword !== undefined) {
_toggleVisibility(togglePassword);
}
}, [togglePassword]);
useEffect(() => {
if (isFocusedState || value !== '') {
if (halfTop !== 0) {
animateFocus();
}
} else {
animateBlur();
}
}, [isFocusedState, halfTop]);
useImperativeHandle(ref, () => ({
focus() {
inputRef.current.focus();
},
blur() {
inputRef.current.blur();
},
}));
useEffect(() => {
if (
!staticLabel &&
customLabelStyles.topFocused === undefined &&
isFocusedState
) {
ReactAnimated.parallel([
timing(leftAnimated, {
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
toValue: customLabelStyles.leftFocused
? customLabelStyles.leftFocused
: 0,
}),
timing(fontSizeAnimated, {
toValue: customLabelStyles.fontSizeFocused
? customLabelStyles.fontSizeFocused
: 10,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
timing(topAnimated, {
toValue: customLabelStyles.topFocused
? customLabelStyles.topFocused
: -halfTop +
(isFocusedState
? customLabelStyles.fontSizeFocused
? customLabelStyles.fontSizeFocused
: 10
: customLabelStyles.fontSizeBlurred
? customLabelStyles.fontSizeBlurred
: 14),
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
// @ts-ignore
timing(fontColorAnimated, {
toValue: 1,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
]).start();
} else if (staticLabel && isFocusedState) {
Animated.timing(fontColorAnimated, {
toValue: 1,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}).start();
}
}, [halfTop]);
function animateFocus() {
if (!staticLabel) {
ReactAnimated.parallel([
timing(leftAnimated, {
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
toValue: customLabelStyles.leftFocused
? customLabelStyles.leftFocused
: 0,
}),
timing(fontSizeAnimated, {
toValue: customLabelStyles.fontSizeFocused
? customLabelStyles.fontSizeFocused
: 10,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
timing(topAnimated, {
toValue: customLabelStyles.topFocused
? customLabelStyles.topFocused
: -halfTop +
(isFocusedState
? customLabelStyles.fontSizeFocused
? customLabelStyles.fontSizeFocused
: 10
: customLabelStyles.fontSizeBlurred
? customLabelStyles.fontSizeBlurred
: 14),
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
// @ts-ignore
timing(fontColorAnimated, {
toValue: 1,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
]).start();
} else {
Animated.timing(fontColorAnimated, {
toValue: 1,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}).start();
}
}
function animateBlur() {
if (!staticLabel) {
ReactAnimated.parallel([
timing(leftAnimated, {
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
toValue: customLabelStyles.leftBlurred
? customLabelStyles.leftBlurred
: 0,
}),
timing(fontSizeAnimated, {
toValue: customLabelStyles.fontSizeBlurred
? customLabelStyles.fontSizeBlurred
: 14,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
timing(topAnimated, {
toValue: customLabelStyles.topBlurred
? customLabelStyles.topBlurred
: 0,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
// @ts-ignore
timing(fontColorAnimated, {
toValue: 0,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}),
]).start();
} else {
Animated.timing(fontColorAnimated, {
toValue: 0,
duration: animationDuration ? animationDuration : 300,
easing: EasingNode.linear,
}).start();
}
}
function handleFocus() {
setIsFocused(true);
}
function handleBlur() {
if (value === '') {
setIsFocused(false);
}
}
function setFocus() {
inputRef.current?.focus();
}
function setBlur() {
inputRef.current?.blur();
}
function _toggleVisibility(toggle?: boolean) {
if (toggle === undefined) {
if (onTogglePassword) {
onTogglePassword(!secureText);
}
setSecureText(!secureText);
secureText ? setFocus() : setBlur();
} else {
if (!((secureText && !toggle) || (!secureText && toggle))) {
if (onTogglePassword) {
onTogglePassword(!toggle);
}
setSecureText(!toggle);
toggle ? setFocus() : setBlur();
}
}
}
function onSubmitEditing() {
if (onSubmit !== undefined) {
onSubmit();
}
}
const imgSource = darkTheme
? secureText
? customShowPasswordImage || makeVisibleBlack
: customHidePasswordImage || makeInvisibleBlack
: secureText
? customShowPasswordImage || makeVisibleWhite
: customHidePasswordImage || makeInvisibleWhite;
const style: TextStyle = {
...setGlobalStyles?.labelStyles,
...labelStyles,
left: labelStyles?.left !== undefined ? labelStyles?.left : 5,
fontSize: staticLabel
? customLabelStyles?.fontSizeFocused !== undefined
? customLabelStyles.fontSizeFocused
: 10
: !isFocusedState
? customLabelStyles.fontSizeBlurred
: customLabelStyles.fontSizeFocused,
// @ts-ignore
color: interpolateColors(fontColorAnimated, {
inputRange: [0, 1],
outputColorRange: [
// @ts-ignore
customLabelStyles.colorBlurred,
// @ts-ignore
customLabelStyles.colorFocused,
],
}),
alignSelf: 'center',
position: 'absolute',
flex: 1,
zIndex: 999,
};
let input: TextStyle =
inputStyles !== undefined
? inputStyles
: setGlobalStyles?.inputStyles !== undefined
? setGlobalStyles.inputStyles
: styles.input;
input = {
...input,
flex: 1,
color:
input.color !== undefined ? input.color : customLabelStyles.colorFocused,
zIndex: style?.zIndex !== undefined ? style.zIndex - 2 : 0,
};
containerStyles =
containerStyles !== undefined
? containerStyles
: setGlobalStyles?.containerStyles !== undefined
? setGlobalStyles?.containerStyles
: styles.container;
containerStyles = {
...containerStyles,
alignItems: 'center',
flexDirection: 'row',
flex: 1,
zIndex: style?.zIndex !== undefined ? style.zIndex - 6 : 0,
};
let toggleButton =
showPasswordContainerStyles !== undefined
? showPasswordContainerStyles
: setGlobalStyles?.showPasswordContainerStyles !== undefined
? setGlobalStyles.showPasswordContainerStyles
: styles.toggleButton;
toggleButton = {
...toggleButton,
alignSelf: 'center',
};
let img =
showPasswordImageStyles !== undefined
? showPasswordImageStyles
: setGlobalStyles?.showPasswordImageStyles !== undefined
? setGlobalStyles.showPasswordImageStyles
: styles.img;
img = {
height: 25,
width: 25,
...img,
};
const countdown = {
...styles.countdown,
...setGlobalStyles?.showCountdownStyles,
...showCountdownStyles,
};
function onChangeTextCallback(val: string): void | undefined {
if (onChangeText === undefined) return undefined;
if (maskType === undefined && mask === undefined) return onChangeText(val);
let newValue: string | undefined;
if (maskType !== 'currency' && mask !== undefined) {
newValue = getValueWithNonCurrencyMask({ value: val, mask });
}
if (maskType === 'currency') {
if (
currency !== undefined &&
!/^[0-9]+$/g.test(val.replace(/[.,]/g, '').replace(currency, '')) &&
val.replace(/[.,]/g, '').replace(currency, '') !== ''
) {
return undefined;
} else if (
currency === undefined &&
!/^[0-9]+$/g.test(val.replace(/[.,]/g, '')) &&
val.replace(/[.,]/g, '') !== ''
) {
return undefined;
}
newValue = getValueWithCurrencyMask({
value: currency !== undefined ? value.replace(currency, '') : value,
newValue: currency !== undefined ? val.replace(currency, '') : val,
currencyDivider,
maxDecimalPlaces,
});
}
if (newValue !== undefined) {
return onChangeText((currency !== undefined ? currency : '') + newValue);
}
}
function onLayout(event: LayoutChangeEvent) {
const { height } = event.nativeEvent.layout;
setHalfTop(height / 2);
}
return (
<TouchableWithoutFeedback onPress={setFocus} onLayout={onLayout}>
<View style={{ flexDirection: 'row' }}>
{staticLabel && (
<AnimatedText
{...labelProps}
onPress={setFocus}
style={[
style,
{
left: labelStyles?.left
? labelStyles?.left
: customLabelStyles.leftFocused
? customLabelStyles.leftFocused
: 20,
top: -(style?.fontSize ? style?.fontSize : 10) / 2,
},
]}
>
{label}
</AnimatedText>
)}
<View style={containerStyles}>
{leftComponent && leftComponent}
<View style={{ flex: 1, flexDirection: 'row' }}>
{!staticLabel && (
<AnimatedText
{...labelProps}
onPress={setFocus}
style={[
style,
// @ts-ignore
{
fontSize: fontSizeAnimated,
transform: [
{ translateX: leftAnimated },
{ translateY: topAnimated },
],
},
]}
>
{label}
</AnimatedText>
)}
<TextInput
value={value}
onSubmitEditing={onSubmitEditing}
secureTextEntry={
isPassword !== undefined ? isPassword && secureText : false
}
onFocus={onFocus !== undefined ? onFocus : handleFocus}
onBlur={onBlur !== undefined ? onBlur : handleBlur}
ref={inputRef}
{...rest}
maxLength={
mask !== undefined
? mask.length
: maxLength !== undefined
? maxLength
: undefined
}
placeholderTextColor={hintTextColor}
placeholder={(staticLabel || isFocusedState) && hint ? hint : ''}
multiline={multiline}
onChangeText={onChangeTextCallback}
style={input}
/>
{rightComponent && rightComponent}
{isPassword && (
<TouchableOpacity
style={toggleButton}
onPress={() => _toggleVisibility()}
>
{secureText && customShowPasswordComponent !== undefined ? (
customShowPasswordComponent
) : !secureText && customHidePasswordComponent !== undefined ? (
customHidePasswordComponent
) : (
<Image source={imgSource} resizeMode="contain" style={img} />
)}
</TouchableOpacity>
)}
</View>
{showCountdown && maxLength && (
<Text style={countdown}>
{maxLength - (value ? value.length : 0)} {countdownLabel}
</Text>
)}
</View>
</View>
</TouchableWithoutFeedback>
);
}
Example #22
Source File: ButtonMultiline.tsx From mobile with Apache License 2.0 | 4 votes |
ButtonMultiline = ({
text,
text1,
onPress,
variant,
color: buttonColorName,
disabled,
loading,
externalLink,
internalLink,
}: ButtonMultilineProps) => {
const i18n = useI18n();
const theme = useTheme<Theme>();
const variantProps = theme.buttonVariants[variant];
const disabledProps = disabled ? variantProps.disabled || {} : {};
const themedStyles = {...variantProps, ...disabledProps};
const {fontSize, fontWeight, fontFamily, color, borderWidth, height} = (themedStyles as unknown) as TextStyle &
ViewStyle;
const textColor = themedStyles.textColor;
const buttonColor = buttonColorName && theme.colors[buttonColorName];
const onPressHandler = loading ? () => {} : onPress;
const externalLinkProps = externalLink
? {
accessibilityLabel: text,
accessibilityHint: i18n.translate('Home.ExternalLinkHint'),
accessibilityRole: 'link' as AccessibilityRole,
}
: {};
const externalArrowIcon = textColor === palette.white ? 'icon-external-arrow-light' : 'icon-external-arrow';
const borderRadius = 10;
const boxStyles: BoxProps['style'] = {
backgroundColor: Platform.OS === 'ios' ? color : 'transparent',
minHeight: height,
borderWidth,
borderColor: buttonColor,
};
const content = (
<Box
borderRadius={borderRadius}
alignItems="center"
justifyContent="center"
style={boxStyles}
paddingHorizontal="m"
paddingVertical="m"
flexDirection="row"
>
{loading ? (
<ActivityIndicator color={textColor} size="large" />
) : (
<>
<Box
flex={1}
flexBasis="100%"
flexDirection="row-reverse"
alignItems="flex-start"
justifyContent="flex-start"
>
<Box flexBasis={25} style={{...styles.iconOffset}}>
{externalLink && <Icon name={externalArrowIcon} size={25} />}
{internalLink && <Icon name="icon-chevron-white" size={25} />}
</Box>
<Box flex={1} flexBasis="90%" alignItems="flex-start" justifyContent="flex-end">
<Text
style={{
...styles.content,
color: textColor || buttonColor,
fontFamily,
fontSize,
...styles.strong,
}}
>
{text}
</Text>
<Text style={{...styles.content, color: textColor || buttonColor, fontWeight, fontFamily, fontSize}}>
{text1}
</Text>
</Box>
</Box>
</>
)}
</Box>
);
const accessibilityProps = {
accessibilityRole: 'button' as 'button',
accessibilityState: {disabled},
...externalLinkProps,
};
if (Platform.OS === 'android') {
return (
<Ripple
disabled={disabled}
onPress={onPressHandler}
backgroundColor={color}
borderRadius={borderRadius}
{...accessibilityProps}
>
{content}
</Ripple>
);
}
return (
<TouchableOpacity
activeOpacity={0.6}
onPress={onPressHandler}
style={styles.stretch}
disabled={disabled}
{...accessibilityProps}
>
{content}
</TouchableOpacity>
);
}
Example #23
Source File: index.tsx From frontatish with MIT License | 4 votes |
Searchbar = (props: SearchbarProps) => {
const Colors = useColors();
const styles = getStyles(Colors);
// destructure custom props and TextInput props separately
const customProps = getCustomProps(props);
const textInputProps = getTextInputProps(customProps, props);
const {
backIcon,
backIconStyle,
clearIcon,
clearIconStyle,
containerStyle,
inputStyle,
leftIcon,
leftIconStyle,
leftLogo,
leftLogoStyle,
onBackIconPress,
onClearIconPress,
onLeftIconPress,
onLeftLogoPress,
onRightIconPress,
onRightLogoPress,
onPress,
rightIcon,
rightIconStyle,
rightLogo,
rightLogoStyle,
showClearIcon,
showBackIcon,
} = customProps;
const { onChangeText, editable, value } = textInputProps;
const renderClearIcon = () => {
if (!showClearIcon) {
return null;
}
// we have to show transparent clear icon when value in textinput is empty
// otherwise the text will move left once the clear icon is rendered
const opacity = value ? 1 : 0;
const onPressUtil = () => {
if (opacity) {
if (onClearIconPress) {
onClearIconPress();
} else if (onChangeText) {
onChangeText('');
}
}
};
return renderIcon(clearIcon, clearIconStyle, onPressUtil, opacity);
};
const renderBackIcon = () => {
if (!showBackIcon) {
return null;
}
const opacity = 1;
return renderIcon(backIcon, backIconStyle, onBackIconPress, opacity);
};
const renderLogo = (
name: ImageSourcePropType,
logoStyle: StyleProp<ImageStyle> | undefined,
onLogoPress: (() => void) | undefined,
) => {
const source = name;
const onPressUtil = onLogoPress || onPress;
return (
<TouchableWithoutFeedback onPress={onPressUtil}>
<Image
source={source}
style={{
alignSelf: 'center',
height: customScaleDimension(30, 'width', 0.2),
width: customScaleDimension(30, 'width', 0.2),
...(logoStyle as object),
}}
/>
</TouchableWithoutFeedback>
);
};
const renderIcon = (
name: string | undefined,
iconStyle: StyleProp<TextStyle> | undefined,
onIconPress: (() => void) | undefined,
opacity: number,
) => {
const onPressUtil = onIconPress || onPress;
return (
<Icon
name={name}
size={customScaleDimension(30, 'width', 0.2)}
onPress={onPressUtil}
color={Colors.font_1}
style={{ opacity, alignSelf: 'center', ...(iconStyle as object) }}
/>
);
};
const renderLogoOrIcon = (
logo: ImageSourcePropType | undefined,
logoStyle: StyleProp<ImageStyle> | undefined,
onLogoPress: (() => void) | undefined,
icon: string | undefined,
iconStyle: StyleProp<TextStyle> | undefined,
onIconPress: (() => void) | undefined,
) => {
if (logo) {
return renderLogo(logo, logoStyle, onLogoPress);
}
if (icon) {
const opacity = 1;
return renderIcon(icon, iconStyle, onIconPress, opacity);
}
return null;
};
const renderLeft = () => {
if (!editable) {
return renderLogoOrIcon(
leftLogo,
leftLogoStyle,
onLeftLogoPress,
leftIcon,
leftIconStyle,
onLeftIconPress,
);
}
return renderBackIcon();
};
const renderRight = () => {
if (!editable) {
return renderLogoOrIcon(
rightLogo,
rightLogoStyle,
onRightLogoPress,
rightIcon,
rightIconStyle,
onRightIconPress,
);
}
return renderClearIcon();
};
// define some default values
const searchbarContainerStyle = containerStyle
? { ...styles.searchbarContainer, ...(containerStyle as object) }
: styles.searchbarContainer;
const searchbarTextInputStyle = inputStyle
? { ...styles.textInput, ...(inputStyle as object) }
: styles.textInput;
textInputProps.onTouchStart = editable
? textInputProps.onTouchStart
: onPress;
textInputProps.selectionColor = textInputProps.selectionColor
? textInputProps.selectionColor
: Colors.primary;
textInputProps.placeholderTextColor = textInputProps.placeholderTextColor
? textInputProps.placeholderTextColor
: Colors.font_3;
return (
<TouchableWithoutFeedback onPress={onPress}>
<View style={searchbarContainerStyle}>
{renderLeft()}
<TextInput {...textInputProps} style={searchbarTextInputStyle} />
{renderRight()}
</View>
</TouchableWithoutFeedback>
);
}
Example #24
Source File: TextField.tsx From react-native-jigsaw with MIT License | 4 votes |
render() {
const {
Icon,
type = "underline",
disabled = false,
label,
error = false,
leftIconName,
leftIconMode,
rightIconName,
assistiveText,
underlineColor: underlineColorProp,
multiline = false,
numberOfLines = 4,
style,
theme: { colors, typography, roundness, disabledOpacity },
render = (props) => <NativeTextInput {...props} />,
...rest
} = this.props;
const MINIMIZED_LABEL_Y_OFFSET = -(typography.caption.lineHeight + 4);
const OUTLINE_MINIMIZED_LABEL_Y_OFFSET = -(16 * 0.5 + 4);
const MAXIMIZED_LABEL_FONT_SIZE = typography.subtitle1.fontSize;
const MINIMIZED_LABEL_FONT_SIZE = typography.caption.fontSize;
const hasActiveOutline = this.state.focused || error;
let inputTextColor,
activeColor,
underlineColor,
borderColor,
placeholderColor,
containerStyle: StyleProp<ViewStyle>,
backgroundColor,
inputStyle: StyleProp<TextStyle>;
inputTextColor = colors.strong;
if (disabled) {
activeColor = colors.light;
placeholderColor = colors.light;
borderColor = "transparent";
underlineColor = "transparent";
backgroundColor = colors.divider;
} else {
activeColor = error ? colors.error : colors.primary;
placeholderColor = borderColor = colors.light;
underlineColor = underlineColorProp;
backgroundColor = colors.background;
}
if (rest.placeholderTextColor) {
placeholderColor = rest.placeholderTextColor;
}
const { lineHeight, ...subtitle1 } = typography.subtitle1;
inputStyle = {
paddingVertical: 0,
color: inputTextColor,
paddingLeft:
leftIconName && leftIconMode === "inset"
? ICON_SIZE + 12 + (type === "solid" ? 16 : 0)
: 0,
paddingRight: rightIconName ? ICON_SIZE + 16 + 4 : 12,
...subtitle1,
};
if (!multiline) {
inputStyle.height = lineHeight;
}
let assistiveTextLeftMargin;
if (type === "underline") {
containerStyle = {
borderTopLeftRadius: roundness,
borderTopRightRadius: roundness,
paddingBottom: 12,
marginTop: 16,
};
if (leftIconName && leftIconMode === "outset") {
assistiveTextLeftMargin = ICON_SIZE + 8;
} else {
assistiveTextLeftMargin = 0;
}
} else {
containerStyle = {
borderRadius: roundness,
borderColor: hasActiveOutline ? activeColor : borderColor,
borderWidth: 1,
paddingTop: label ? 16 * 1.5 : 16,
paddingBottom: label ? 16 * 0.5 : 16,
opacity: disabled ? disabledOpacity : 1,
backgroundColor,
};
if (leftIconName && leftIconMode === "inset") {
assistiveTextLeftMargin = 16 + 4;
} else if (leftIconName && leftIconMode === "outset") {
assistiveTextLeftMargin = ICON_SIZE + 8 + 12;
} else {
assistiveTextLeftMargin = 12;
}
inputStyle.paddingHorizontal = 12;
}
if (leftIconName && leftIconMode === "outset") {
containerStyle.marginLeft = ICON_SIZE + 8;
}
let leftIconColor;
if (error) {
leftIconColor = colors.error;
} else if (this.state.focused) {
leftIconColor = colors.primary;
} else {
leftIconColor = colors.light;
}
const leftIconProps = {
size: 24,
color: leftIconColor,
name: leftIconName || "",
};
const leftIconStyle: ImageStyle = {
position: "absolute",
marginTop:
type === "solid"
? MINIMIZED_LABEL_FONT_SIZE + 4
: leftIconMode === "outset"
? 16
: 0,
marginLeft: leftIconMode === "inset" && type === "solid" ? 16 : 0,
};
const labelStyle = {
...typography.subtitle1,
top: type === "solid" ? 16 : 0,
left:
leftIconName && leftIconMode === "inset"
? ICON_SIZE + (type === "solid" ? 16 : 12)
: 0,
transform: [
{
// Move label to top
translateY: this.state.labeled.interpolate({
inputRange: [0, 1],
outputRange: [
type === "solid"
? OUTLINE_MINIMIZED_LABEL_Y_OFFSET
: MINIMIZED_LABEL_Y_OFFSET,
0,
],
}),
},
{
// Make label smaller
scale: this.state.labeled.interpolate({
inputRange: [0, 1],
outputRange: [
MINIMIZED_LABEL_FONT_SIZE / MAXIMIZED_LABEL_FONT_SIZE,
1,
],
}),
},
{
// Offset label scale since RN doesn't support transform origin
translateX: this.state.labeled.interpolate({
inputRange: [0, 1],
outputRange: [
-(1 - MINIMIZED_LABEL_FONT_SIZE / MAXIMIZED_LABEL_FONT_SIZE) *
(this.state.labelLayout.width / 2),
0,
],
}),
},
],
};
const { textStyles } = extractStyles(style);
const inputStyles = applyStyles(
[
styles.input,
inputStyle,
type === "solid" ? { marginHorizontal: 12 } : {},
],
textStyles
);
const {
backgroundColor: bgColor,
padding,
paddingTop,
paddingBottom,
paddingLeft,
paddingRight,
borderRadius,
borderWidth,
borderTopWidth,
borderRightWidth,
borderBottomWidth,
borderLeftWidth,
borderColor: borderCol,
...styleProp
} = StyleSheet.flatten(style || {}) as ViewStyle & { height?: number };
return (
<View style={[styles.container, styleProp]}>
{leftIconName && leftIconMode === "outset" ? (
<Icon {...leftIconProps} style={leftIconStyle} />
) : null}
<View
style={applyStyles([containerStyle], {
height: style?.height,
backgroundColor: bgColor,
padding,
paddingTop,
paddingBottom,
paddingLeft,
paddingRight,
borderRadius,
borderWidth,
borderTopWidth,
borderRightWidth,
borderBottomWidth,
borderLeftWidth,
borderColor: borderCol,
})}
>
{type === "underline" ? (
// When type === 'flat', render an underline
<Animated.View
style={[
styles.underline,
{
backgroundColor:
bgColor ||
(error
? colors.error
: this.state.focused
? activeColor
: underlineColor),
// Underlines is thinner when input is not focused
transform: [{ scaleY: this.state.focused ? 1 : 0.5 }],
},
]}
/>
) : null}
{label ? (
// Position colored placeholder and gray placeholder on top of each other and crossfade them
// This gives the effect of animating the color, but allows us to use native driver
<View
pointerEvents="none"
style={[
StyleSheet.absoluteFill,
{
opacity:
// Hide the label in minimized state until we measure its width
this.state.value || this.state.focused
? this.state.labelLayout.measured
? 1
: 0
: 1,
},
]}
>
<AnimatedText
onLayout={(e: LayoutChangeEvent) =>
this.setState({
labelLayout: {
width: e.nativeEvent.layout.width,
measured: true,
},
})
}
style={[
styles.placeholder,
type === "solid" ? { paddingHorizontal: 12 } : {},
labelStyle,
{
color: placeholderColor,
opacity: this.state.labeled.interpolate({
inputRange: [0, 1],
outputRange: [hasActiveOutline ? 1 : 0, 0],
}),
},
]}
numberOfLines={1}
>
{label}
</AnimatedText>
<AnimatedText
style={[
styles.placeholder,
type === "solid" ? { paddingHorizontal: 12 } : {},
labelStyle,
{
color: placeholderColor,
opacity: hasActiveOutline ? this.state.labeled : 1,
},
]}
numberOfLines={1}
>
{label}
</AnimatedText>
</View>
) : null}
{leftIconName && leftIconMode === "inset" ? (
<View
style={{
justifyContent: type === "solid" ? "center" : undefined,
}}
>
<Icon {...leftIconProps} style={leftIconStyle} />
</View>
) : null}
{render({
ref: (c: NativeTextInput) => {
this._root = c;
},
onChange: this._handleChangeText,
placeholder: label
? this.state.placeholder
: this.props.placeholder,
placeholderTextColor: placeholderColor,
editable: !disabled,
selectionColor: activeColor,
multiline,
numberOfLines,
onFocus: this._handleFocus,
onBlur: this._handleBlur,
underlineColorAndroid: "transparent",
style: inputStyles,
...rest,
value: this.state.value,
})}
</View>
{rightIconName ? (
<Icon
name={rightIconName}
size={ICON_SIZE}
color={colors.light}
style={{
position: "absolute",
right: 16,
marginTop: type === "solid" ? MINIMIZED_LABEL_FONT_SIZE + 4 : 16,
}}
/>
) : null}
{assistiveText ? (
<Text
style={[
{
color: error ? colors.error : colors.light,
marginTop: 8,
marginLeft: assistiveTextLeftMargin,
},
]}
>
{assistiveText}
</Text>
) : null}
</View>
);
}
Example #25
Source File: ProgressBarHaflCircle.tsx From companion-kit with MIT License | 4 votes |
export default function ProgressBarHaflCircle(this: never, props: PropsGradient) {
const { animationStep, title, diameter, gradient, progress, style, titleStyle } = props;
const length = Math.round(diameter * Math.PI);
const [ offset ] = React.useState(() => {
const startProgress = (progress - (animationStep || 0.1));
return new Animated.Value(getOffset(diameter, startProgress));
});
React.useEffect(() => {
Animated.timing(offset, {
toValue: getOffset(diameter, progress),
duration: 2000,
delay: 750,
}).start();
}, [progress]);
const boxSize = diameter + 6;
const origin = diameter / 2;
const defaultTitleStyles: StyleProp<TextStyle> = {
position: 'absolute',
alignItems: 'center',
justifyContent: 'center',
};
return (
<View style={style}>
<Text style={[TextStyles.p3, defaultTitleStyles, titleStyle]}>{title}</Text>
<Svg id="progress-bar-circle" width="100%" height="100%" viewBox={`0 0 ${boxSize} ${boxSize}`} fill="none">
<G x={3} y={3}>
<Circle
id="circle-bg"
opacity="0.2"
cx={diameter / 2}
cy={diameter / 2}
r={diameter / 2}
strokeWidth="3"
stroke="url(#paint0_linear)"
fill="none"
/>
<AnimatedContainer
id="circle-progress"
fill="none"
cx={diameter / 2}
cy={diameter / 2}
r={diameter / 2}
strokeWidth="3"
stroke="url(#paint0_linear)"
strokeDasharray={length}
strokeDashoffset={offset}
origin={`${origin}, ${origin}`}
rotation={90}
/>
<AnimatedContainer
id="circle-progress2"
fill="none"
cx={diameter / 2}
cy={diameter / 2}
r={diameter / 2}
strokeWidth="3"
stroke="url(#paint0_linear)"
strokeDasharray={length}
strokeDashoffset={offset}
origin={`${origin}, ${origin}`}
scaleX={-1}
rotation={-90}
/>
</G>
<Defs>
{gradient ? (
<LinearGradient id="paint0_linear" x1={diameter / 2} y1={diameter} x2={diameter} y2={0} gradientUnits="userSpaceOnUse">
{gradient.map((color, i) => {
// tslint:disable-next-line: no-unused-expression
return <Stop key={`${color.title}_${i}`} offset={color.offset} stopColor={color.title}/>;
})}
</LinearGradient>
) : (
<LinearGradient id="paint0_linear" x1={0} y1={diameter / 2} x2={diameter} y2={diameter / 2} gradientUnits="userSpaceOnUse">
<Stop offset="0.0996095" stopColor="#FFCECF"/>
<Stop offset="0.238673" stopColor="#9A87E7"/>
<Stop offset="0.384948" stopColor="#FFAFD5"/>
<Stop offset="0.512681" stopColor="#FA8989"/>
<Stop offset="0.642474" stopColor="#CFC4FF"/>
<Stop offset="0.776388" stopColor="#FFAFD5"/>
<Stop offset="0.90206" stopColor="#FFCED0"/>
</LinearGradient>
)}
</Defs>
</Svg>
</View>
);
}
Example #26
Source File: DeprecatedFAB.tsx From react-native-jigsaw with MIT License | 4 votes |
FAB: React.FC<Props> = ({
Icon,
icon,
disabled = false,
type = "solid",
loading = false,
color: colorOverride,
label,
onPress,
elevation = 0,
style,
theme: { colors, disabledOpacity, roundness, typography },
...rest
}) => {
let backgroundColor, borderColor, textColor, borderWidth;
const buttonColor = colorOverride || colors.primary;
if (type === "standard" || type === "extended" || type === "fixed") {
backgroundColor = buttonColor;
if (disabled) {
textColor = color(colors.surface).alpha(disabledOpacity).rgb().string();
} else {
textColor = colors.surface;
}
} else {
backgroundColor = "transparent";
if (disabled) {
textColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
} else {
textColor = buttonColor;
}
}
if (type === "outline") {
if (disabled) {
borderColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
} else {
borderColor = buttonColor;
}
borderWidth = StyleSheet.hairlineWidth;
} else {
borderColor = "transparent";
borderWidth = 0;
}
const buttonStyle: StyleProp<ViewStyle> = {
backgroundColor,
borderColor,
borderWidth,
borderRadius: roundness,
alignItems: "center",
justifyContent: "center",
};
const buttonStyles: StyleProp<ViewStyle>[] = [styles.button, buttonStyle];
const contentStyle: StyleProp<ViewStyle>[] = [styles.content];
const textStyle: StyleProp<TextStyle> = {
textAlign: "center",
color: textColor,
};
const iconStyle: StyleProp<ViewStyle>[] = [
styles.icon,
{
width: Config.buttonIconSize,
},
];
if (type === "standard" || type === "outline") {
buttonStyle.width = Config.FABSize;
buttonStyle.height = Config.FABSize;
buttonStyle.borderRadius = Config.FABBorderRadius;
contentStyle.push({
width: Config.FABSize,
height: Config.FABSize,
});
}
if (type === "extended" || type === "fixed") {
iconStyle.push({
marginLeft: 16,
marginRight: -8,
});
textStyle.margin = 16;
}
if (type === "fixed") {
buttonStyles.push({
height: Config.FABFixedHeight,
alignSelf: "stretch",
});
}
return (
<Elevation style={[{ elevation }, style]}>
<Touchable
{...rest}
onPress={onPress}
accessibilityState={{ disabled }}
accessibilityRole="button"
disabled={disabled || loading}
style={buttonStyles}
>
<View style={styles.content}>
{icon && loading !== true ? (
<View style={iconStyle}>
<Icon
name={icon}
size={Config.buttonIconSize}
color={textColor}
/>
</View>
) : null}
{loading ? (
<ActivityIndicator
size="small"
color={textColor}
style={iconStyle}
/>
) : null}
{label ? (
<Text numberOfLines={1} style={[textStyle, typography.button]}>
{label}
</Text>
) : null}
</View>
</Touchable>
</Elevation>
);
}
Example #27
Source File: DeprecatedButton.tsx From react-native-jigsaw with MIT License | 4 votes |
Button: React.FC<Props> = ({
Icon,
icon,
disabled = false,
type = "solid",
loading = false,
labelColor,
color: colorOverride,
children,
onPress,
elevation = 0,
style,
theme: { colors, disabledOpacity, roundness, typography },
...rest
}) => {
let backgroundColor, borderColor, textColor, borderWidth;
const buttonColor = colorOverride || colors.primary;
if (type === "solid") {
backgroundColor = buttonColor;
if (disabled) {
textColor = color(colors.surface).alpha(disabledOpacity).rgb().string();
} else {
textColor = labelColor || colors.surface;
}
} else {
backgroundColor = "transparent";
if (disabled) {
textColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
} else {
textColor = labelColor || buttonColor;
}
}
if (type === "outline") {
if (disabled) {
borderColor = color(buttonColor).alpha(disabledOpacity).rgb().string();
} else {
borderColor = buttonColor;
}
borderWidth = StyleSheet.hairlineWidth;
} else {
borderColor = "transparent";
borderWidth = 0;
}
const buttonStyle = {
backgroundColor,
borderColor,
borderWidth,
borderRadius: roundness,
};
const textStyle: StyleProp<TextStyle> = {
textAlign: "center",
color: textColor,
marginVertical: 16,
marginHorizontal: 16,
};
const iconStyle = [
styles.icon,
{
marginLeft: 16,
marginRight: -8,
width: Config.buttonIconSize,
},
];
const {
margin,
marginEnd,
marginTop,
marginLeft,
marginRight,
marginBottom,
marginHorizontal,
marginVertical,
...innerStyles
} = StyleSheet.flatten(style || {});
const margins = {
margin,
marginEnd,
marginTop,
marginLeft,
marginRight,
marginBottom,
marginHorizontal,
marginVertical,
};
return (
<Elevation style={{ elevation, alignSelf: "stretch", ...margins }}>
<Touchable
{...rest}
onPress={onPress}
accessibilityState={{ disabled }}
accessibilityRole="button"
disabled={disabled || loading}
style={[styles.button, buttonStyle, innerStyles]}
>
<View style={styles.content}>
{icon && loading !== true ? (
<View style={iconStyle}>
<Icon
name={icon}
size={Config.buttonIconSize}
color={textColor}
/>
</View>
) : null}
{loading ? (
<ActivityIndicator
size="small"
color={textColor}
style={iconStyle}
/>
) : null}
<Text numberOfLines={1} style={[textStyle, typography.button]}>
{children}
</Text>
</View>
</Touchable>
</Elevation>
);
}
Example #28
Source File: DatePicker.tsx From react-native-jigsaw with MIT License | 4 votes |
DatePicker: React.FC<Props> = ({
Icon,
style,
theme: { colors, typography, roundness, disabledOpacity },
date,
onDateChange = () => {},
defaultValue,
disabled = false,
mode = "date",
format,
type = "underline",
leftIconName,
rightIconName,
leftIconMode = "inset",
label,
placeholder,
...props
}) => {
const [value, setValue] = React.useState<any>(date || defaultValue);
React.useEffect(() => {
if (defaultValue != null) {
setValue(defaultValue);
}
}, [defaultValue]);
const [pickerVisible, setPickerVisible] = React.useState(false);
const [labeled] = React.useState<Animated.Value>(
new Animated.Value(date ? 0 : 1)
);
const [placeholder1, setPlaceholder1] = React.useState("");
const [focused, setFocused] = React.useState<boolean>(false);
const [labelLayout, setLabelLayout] = React.useState<{
measured: Boolean;
width: number;
}>({ measured: false, width: 0 });
const getValidDate = (): Date => {
if (!value) {
return new Date();
}
return typeof value?.getMonth === "function" ? value : new Date();
};
const formatDate = (): string => {
if (!value) return "";
let newDate = getValidDate();
if (format) return dateFormat(newDate, format);
if (mode === "time") {
return `${newDate.toLocaleTimeString()}`;
}
if (mode === "datetime") {
return `${newDate.toLocaleString()}`;
}
return `${
MONTHS[newDate.getMonth()]
} ${newDate.getDate()}, ${newDate.getFullYear()}`;
};
const toggleVisibility = async () => {
setPickerVisible(!pickerVisible);
focused ? _handleBlur() : _handleFocus();
};
const insets = useSafeAreaInsets();
// const _restoreLabel = () =>
// Animated.timing(labeled, {
// toValue: 1,
// duration: FOCUS_ANIMATION_DURATION,
// useNativeDriver: true,
// }).start();
// const _minmizeLabel = () =>
// Animated.timing(labeled, {
// toValue: 0,
// duration: BLUR_ANIMATION_DURATION,
// useNativeDriver: true,
// }).start();
// const _showPlaceholder = () =>
// setTimeout(() => setPlaceholder1(placeholder || ""), 50);
const _hidePlaceholder = () => {
setPlaceholder1("");
};
React.useEffect(() => {
setValue(date);
}, [date]);
React.useEffect(() => {
if (value || focused || placeholder1) {
// _minmizeLabel();
Animated.timing(labeled, {
toValue: 0,
duration: BLUR_ANIMATION_DURATION,
useNativeDriver: true,
}).start();
} else {
// _restoreLabel();
Animated.timing(labeled, {
toValue: 1,
duration: FOCUS_ANIMATION_DURATION,
useNativeDriver: true,
}).start();
}
}, [value, focused, placeholder1, labeled]);
React.useEffect(() => {
const _showPlaceholder = () =>
setTimeout(() => setPlaceholder1(placeholder || ""), 50);
if (focused || !label) {
_showPlaceholder();
} else {
_hidePlaceholder();
}
return () => {
clearTimeout(_showPlaceholder());
};
}, [focused, label, placeholder]);
const _handleFocus = () => {
if (disabled) {
return;
}
setFocused(true);
};
const _handleBlur = () => {
if (disabled) {
return;
}
setFocused(false);
};
const MINIMIZED_LABEL_Y_OFFSET = -(typography.caption.lineHeight + 4);
const OUTLINE_MINIMIZED_LABEL_Y_OFFSET = -(16 * 0.5 + 4);
const MAXIMIZED_LABEL_FONT_SIZE = typography.subtitle1.fontSize;
const MINIMIZED_LABEL_FONT_SIZE = typography.caption.fontSize;
const hasActiveOutline = focused;
let inputTextColor,
activeColor,
underlineColor,
borderColor,
placeholderColor,
containerStyle: StyleProp<ViewStyle>,
backgroundColor,
inputStyle: StyleProp<TextStyle>;
inputTextColor = colors.strong;
if (disabled) {
activeColor = colors.light;
placeholderColor = colors.light;
borderColor = "transparent";
underlineColor = "transparent";
backgroundColor = colors.divider;
} else {
activeColor = colors.primary;
placeholderColor = borderColor = colors.light;
underlineColor = colors.light;
backgroundColor = colors.background;
}
const { lineHeight, ...subtitle1 } = typography.subtitle1;
inputStyle = {
paddingVertical: 0,
color: inputTextColor,
paddingLeft:
leftIconName && leftIconMode === "inset"
? ICON_SIZE + (type === "solid" ? 16 : 12)
: 0,
paddingRight: rightIconName ? ICON_SIZE + 16 + 4 : 12,
...subtitle1,
height: lineHeight,
};
if (type === "underline") {
containerStyle = {
borderTopLeftRadius: roundness,
borderTopRightRadius: roundness,
paddingBottom: 12,
marginTop: 16,
};
} else {
containerStyle = {
borderRadius: roundness,
borderColor: hasActiveOutline ? activeColor : borderColor,
borderWidth: 1,
paddingTop: labeled ? 16 * 1.5 : 16,
paddingBottom: labeled ? 16 * 0.5 : 16,
opacity: disabled ? disabledOpacity : 1,
backgroundColor,
};
inputStyle.paddingHorizontal = 12;
}
if (leftIconName && leftIconMode === "outset") {
containerStyle.marginLeft = ICON_SIZE + 8;
}
let leftIconColor;
if (focused) {
leftIconColor = colors.primary;
} else {
leftIconColor = colors.light;
}
const leftIconProps = {
size: 24,
color: leftIconColor,
name: leftIconName || "",
};
const leftIconStyle: ImageStyle = {
position: "absolute",
marginTop:
type === "solid"
? leftIconMode === "inset"
? MINIMIZED_LABEL_FONT_SIZE + 4
: 16
: leftIconMode === "outset"
? 16
: 0,
};
const labelStyle = {
...typography.subtitle1,
top: type === "solid" ? 16 : 0,
left:
leftIconName && leftIconMode === "inset"
? ICON_SIZE + (type === "solid" ? 16 : 12)
: 0,
transform: [
{
// Move label to top
translateY: labeled.interpolate({
inputRange: [0, 1],
outputRange: [
type === "solid"
? OUTLINE_MINIMIZED_LABEL_Y_OFFSET
: MINIMIZED_LABEL_Y_OFFSET,
0,
],
}),
},
{
// Make label smaller
scale: labeled.interpolate({
inputRange: [0, 1],
outputRange: [
MINIMIZED_LABEL_FONT_SIZE / MAXIMIZED_LABEL_FONT_SIZE,
1,
],
}),
},
{
// Offset label scale since RN doesn't support transform origin
translateX: labeled.interpolate({
inputRange: [0, 1],
outputRange: [
-(1 - MINIMIZED_LABEL_FONT_SIZE / MAXIMIZED_LABEL_FONT_SIZE) *
(labelLayout.width / 2),
0,
],
}),
},
],
};
const inputStyles = [
styles.input,
inputStyle,
type === "solid" ? { marginHorizontal: 12 } : {},
];
// const render = (props) => <NativeTextInput {...props} />;
return (
<View style={[styles.container, style]}>
<Touchable disabled={disabled} onPress={toggleVisibility}>
<View pointerEvents="none">
<View style={[styles.container, style]}>
{leftIconName && leftIconMode === "outset" ? (
<Icon {...leftIconProps} style={leftIconStyle} />
) : null}
<View
style={[containerStyle, style ? { height: style.height } : {}]}
>
{type === "underline" ? (
// When type === 'flat', render an underline
<Animated.View
style={[
styles.underline,
{
backgroundColor: focused ? activeColor : underlineColor,
// Underlines is thinner when input is not focused
transform: [{ scaleY: focused ? 1 : 0.5 }],
},
]}
/>
) : null}
{label ? (
// Position colored placeholder and gray placeholder on top of each other and crossfade them
// This gives the effect of animating the color, but allows us to use native driver
<View
pointerEvents="none"
style={[
StyleSheet.absoluteFill,
{
opacity:
// Hide the label in minimized state until we measure its width
date || focused ? (labelLayout.measured ? 1 : 0) : 1,
},
]}
>
<AnimatedText
onLayout={(e: LayoutChangeEvent) =>
setLabelLayout({
width: e.nativeEvent.layout.width,
measured: true,
})
}
style={[
styles.placeholder,
type === "solid" ? { paddingHorizontal: 12 } : {},
labelStyle,
{
color: colors.light,
opacity: labeled.interpolate({
inputRange: [0, 1],
outputRange: [hasActiveOutline ? 1 : 0, 0],
}),
},
]}
numberOfLines={1}
>
{label}
</AnimatedText>
<AnimatedText
style={[
styles.placeholder,
type === "solid" ? { paddingHorizontal: 12 } : {},
labelStyle,
{
color: placeholderColor,
opacity: hasActiveOutline ? labeled : 1,
},
]}
numberOfLines={1}
>
{label}
</AnimatedText>
</View>
) : null}
{leftIconName && leftIconMode === "inset" ? (
<Icon
{...leftIconProps}
style={{
...leftIconStyle,
marginLeft: type === "solid" ? 16 : 0,
}}
/>
) : null}
<NativeTextInput
value={formatDate()}
placeholder={label ? placeholder1 : placeholder}
editable={!disabled}
placeholderTextColor={placeholderColor}
selectionColor={activeColor}
onFocus={_handleFocus}
onBlur={_handleBlur}
underlineColorAndroid={"transparent"}
style={inputStyles}
{...props}
/>
</View>
{rightIconName ? (
<Icon
name={rightIconName}
size={ICON_SIZE}
color={colors.light}
style={{
position: "absolute",
right: 16,
marginTop:
type === "solid" ? MINIMIZED_LABEL_FONT_SIZE + 4 : 16,
}}
/>
) : null}
</View>
</View>
</Touchable>
{pickerVisible && (
<Portal>
<View
style={[
styles.picker,
{
backgroundColor: colors.divider,
},
]}
>
<View
style={[
styles.pickerContainer,
{
paddingTop: insets.top,
paddingBottom: insets.bottom,
paddingLeft: insets.left,
paddingRight: insets.right,
},
]}
>
<DateTimePicker
value={getValidDate()}
mode={mode}
isVisible={pickerVisible}
toggleVisibility={toggleVisibility}
onChange={(_event: any, data: any) => {
toggleVisibility();
setValue(data);
onDateChange(data);
}}
/>
</View>
</View>
</Portal>
)}
</View>
);
}
Example #29
Source File: IterableInboxMessageCell.tsx From react-native-sdk with MIT License | 4 votes |
function defaultMessageListLayout(
last: boolean,
dataModel: IterableInboxDataModel,
rowViewModel: InboxRowViewModel,
customizations: IterableInboxCustomizations,
isPortrait: boolean
) {
const messageTitle = rowViewModel.inAppMessage.inboxMetadata?.title ?? ""
const messageBody = rowViewModel.inAppMessage.inboxMetadata?.subtitle ?? ""
const messageCreatedAt = dataModel.getFormattedDate(rowViewModel.inAppMessage) ?? ""
const thumbnailURL = rowViewModel.imageUrl
let styles = StyleSheet.create({
unreadIndicatorContainer: {
height: '100%',
flexDirection: 'column',
justifyContent: 'flex-start'
},
unreadIndicator: {
width: 15,
height: 15,
borderRadius: 15 / 2,
backgroundColor: 'blue',
marginLeft: 10,
marginRight: 5,
marginTop: 10
},
unreadMessageThumbnailContainer: {
paddingLeft: 10,
flexDirection: 'column',
justifyContent: 'center'
},
readMessageThumbnailContainer: {
paddingLeft: 30,
flexDirection: 'column',
justifyContent: 'center'
},
messageContainer: {
paddingLeft: 10,
width: '75%',
flexDirection: 'column',
justifyContent: 'center'
},
title: {
fontSize: 22,
width: '85%',
paddingBottom: 10
},
body: {
fontSize: 15,
color: 'lightgray',
width: '85%',
flexWrap: "wrap",
paddingBottom: 10
},
createdAt: {
fontSize: 12,
color: 'lightgray'
},
messageRow: {
flexDirection: 'row',
backgroundColor: 'white',
paddingTop: 10,
paddingBottom: 10,
width: '100%',
height: 150,
borderStyle: 'solid',
borderColor: 'lightgray',
borderTopWidth: 1
}
})
const resolvedStyles = { ...styles, ...customizations }
let {
unreadIndicatorContainer,
unreadIndicator,
unreadMessageThumbnailContainer,
readMessageThumbnailContainer,
messageContainer,
title,
body,
createdAt,
messageRow
} = resolvedStyles
unreadIndicator = (!isPortrait) ? { ...unreadIndicator, marginLeft: 40 } : unreadIndicator
readMessageThumbnailContainer = (!isPortrait) ? { ...readMessageThumbnailContainer, paddingLeft: 65 } : readMessageThumbnailContainer
messageContainer = (!isPortrait) ? { ...messageContainer, width: '90%' } : messageContainer
function messageRowStyle(rowViewModel: InboxRowViewModel) {
return last ? { ...messageRow, borderBottomWidth: 1 } : messageRow
}
return (
<View style={messageRowStyle(rowViewModel) as ViewStyle} >
<View style={unreadIndicatorContainer as ViewStyle}>
{rowViewModel.read ? null : <View style={unreadIndicator} />}
</View>
<View style={(rowViewModel.read ? readMessageThumbnailContainer : unreadMessageThumbnailContainer) as ViewStyle}>
{thumbnailURL ? <Image style={{ height: 80, width: 80 }} source={{ uri: thumbnailURL }} /> : null}
</View>
<View style={messageContainer as ViewStyle}>
<Text numberOfLines={1} ellipsizeMode='tail' style={title}>{messageTitle as TextStyle}</Text>
<Text numberOfLines={3} ellipsizeMode='tail' style={body as TextStyle}>{messageBody}</Text>
<Text style={createdAt}>{messageCreatedAt as TextStyle}</Text>
</View>
</View>
)
}