Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 2x 16x 16x 16x 12x 12x 12x 12x 8x 4x 1x 3x 16x 8x 16x 2x 2x 2x 2x | import React, { useMemo } from "react";
import { Text, StyleSheet, Platform } from "react-native";
import { cn } from "@sb/libs";
import { useInput } from "../Context/InputContext";
interface LabelProps {
/** The text content to display as the label */
label: string;
/** Whether the input is currently focused */
isFocused?: boolean;
/** Whether the input has text content */
hasText?: boolean;
/** Whether to use floating label behavior */
floatingLabel?: boolean;
/** The direction of the input */
direction?: "rtl" | "ltr";
/** Whether the input is disabled */
disabled?: boolean;
/** The style of the placeholder */
placeholderStyle?: string;
}
/**
* Label component for input fields with support for floating labels and status styling
*/
const Label: React.FC<LabelProps> = ({
label,
isFocused = false,
hasText = false,
floatingLabel = false,
direction = "ltr",
disabled = false,
placeholderStyle,
}) => {
const { status, size } = useInput();
const isFloating = floatingLabel;
// Memoize styles to prevent unnecessary recalculations
const labelStyles = useMemo(() => {
const baseStyle = [styles.labelBase, FONTS[size]];
const focusedStyle =
isFocused || hasText
? [styles.labelFocused, FOCUSED_FONTS[size]]
: undefined;
const combinedStyles = StyleSheet.flatten([baseStyle, focusedStyle]);
if (isFloating) {
return combinedStyles;
}
if (!isFocused && !hasText) {
return StyleSheet.flatten(baseStyle);
}
return StyleSheet.flatten([styles.hidden]);
}, [isFloating, isFocused, hasText, size]);
// Memoize className to prevent unnecessary recalculations
const labelClassName = useMemo(() => {
return cn(
"text-primary mb-1 w-full font-normal",
status === "error" && "text-status-error",
status === "success" && "text-status-success",
status === "warning" && "text-status-warning",
direction === "rtl" && "text-right",
disabled && "text-input-disabled-text",
placeholderStyle
);
}, [status, direction, disabled, placeholderStyle]);
return (
<Text
style={labelStyles}
className={labelClassName}
accessibilityRole="text"
>
{label}
</Text>
);
};
const styles = StyleSheet.create({
labelBase: {
marginBottom: 0,
marginTop: Platform.OS === "android" ? -3 : 0,
alignItems: "center",
},
hidden: {
display: "none",
},
labelFocused: {},
labelRTL: {
textAlign: "right",
paddingRight: 5,
},
});
const FONTS = StyleSheet.create({
small: {
fontSize: 10,
},
default: {
fontSize: 14,
},
large: {
fontSize: 18,
},
});
const FOCUSED_FONTS = StyleSheet.create({
small: {
fontSize: 8,
},
default: {
fontSize: 12,
},
large: {
fontSize: 16,
},
});
Label.displayName = "Label";
export default Label;
|