Skip to content

Commit 9bc2892

Browse files
authored
Center pin input cells (#767)
1 parent 7f76e4a commit 9bc2892

File tree

3 files changed

+59
-43
lines changed

3 files changed

+59
-43
lines changed

example/src/PinInputExample.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ const PinInputExample: React.FC = () => {
4646
},
4747
shadowOpacity: 0.32,
4848
shadowRadius: 5.46,
49+
marginStart: 10,
50+
marginEnd: 10,
4951
elevation: 9,
5052
alignItems: "center",
5153
justifyContent: "center",
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import React from "react";
2-
import { StyleProp, ViewStyle, View } from "react-native";
2+
import { StyleProp, ViewStyle, View, LayoutChangeEvent } from "react-native";
33

44
interface CustomPinInputCellProps {
55
style?: StyleProp<ViewStyle>;
6+
onLayout: (event: LayoutChangeEvent) => void;
67
}
78

89
/**
@@ -11,8 +12,8 @@ interface CustomPinInputCellProps {
1112
*/
1213
const CustomPinInputCell: React.FC<
1314
React.PropsWithChildren<CustomPinInputCellProps>
14-
> = ({ style, children }) => {
15-
return <View style={style} children={children} />;
15+
> = (props) => {
16+
return <View {...props} />;
1617
};
1718

1819
export default CustomPinInputCell;

packages/core/src/components/PinInput/PinInput.tsx

Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const PinInput = React.forwardRef<NativeTextInput, PinInputProps>(
4848
renderItem,
4949
value,
5050
onChangeText,
51-
focusedBorderColor,
51+
focusedBorderColor = theme.colors.primary,
5252
focusedBackgroundColor,
5353
focusedBorderWidth,
5454
focusedTextColor,
@@ -82,55 +82,64 @@ const PinInput = React.forwardRef<NativeTextInput, PinInputProps>(
8282
// eslint-disable-next-line react-hooks/exhaustive-deps
8383
}, [value, cellCount, blurOnFull, pinInputRef]);
8484

85+
const renderCell = (
86+
cellValue: string,
87+
index: number,
88+
isFocused: boolean
89+
) => {
90+
const cell = renderItem?.({ cellValue, index, isFocused }) || (
91+
<View
92+
testID="default-code-input-cell"
93+
style={[
94+
styles.cell,
95+
{ borderColor: theme.colors.disabled },
96+
viewStyles,
97+
isFocused && focusedBorderWidth
98+
? { borderWidth: focusedBorderWidth }
99+
: undefined,
100+
isFocused && focusedBorderColor
101+
? { borderColor: focusedBorderColor }
102+
: undefined,
103+
isFocused && focusedBackgroundColor
104+
? { backgroundColor: focusedBackgroundColor }
105+
: undefined,
106+
]}
107+
>
108+
<PinInputText
109+
style={[
110+
styles.cellText,
111+
{ color: theme.colors.strong },
112+
textStyles,
113+
isFocused && focusedTextColor
114+
? { color: focusedTextColor }
115+
: undefined,
116+
]}
117+
isFocused={isFocused}
118+
>
119+
{cellValue}
120+
</PinInputText>
121+
</View>
122+
);
123+
124+
return React.cloneElement(cell, {
125+
onLayout: clearOnCellFocus ? getCellOnLayout(index) : undefined,
126+
});
127+
};
128+
85129
return (
86130
<CodeField
87131
ref={pinInputRef}
88132
{...(clearOnCellFocus ? codeFieldProps : {})}
89133
value={value}
90134
onChangeText={onChangeText}
135+
rootStyle={styles.rootContainer}
91136
textInputStyle={{ height: "100%" }} // addresses issue on firefox where the hidden input did not fill the height
92137
InputComponent={TextInput}
93138
cellCount={cellCount}
94139
renderCell={({ symbol: cellValue, index, isFocused }) => (
95-
<View
96-
key={index}
97-
onLayout={clearOnCellFocus ? getCellOnLayout(index) : undefined}
98-
style={{ flex: 1 }}
99-
>
100-
{renderItem?.({ cellValue, index, isFocused }) || (
101-
<View
102-
testID="default-code-input-cell"
103-
style={[
104-
styles.cell,
105-
{ borderColor: theme.colors.disabled },
106-
viewStyles,
107-
isFocused && focusedBorderWidth
108-
? { borderWidth: focusedBorderWidth }
109-
: undefined,
110-
isFocused && focusedBorderColor
111-
? { borderColor: focusedBorderColor }
112-
: undefined,
113-
isFocused && focusedBackgroundColor
114-
? { backgroundColor: focusedBackgroundColor }
115-
: undefined,
116-
]}
117-
>
118-
<PinInputText
119-
style={[
120-
styles.cellText,
121-
{ color: theme.colors.strong },
122-
textStyles,
123-
isFocused && focusedTextColor
124-
? { color: focusedTextColor }
125-
: undefined,
126-
]}
127-
isFocused={isFocused}
128-
>
129-
{cellValue}
130-
</PinInputText>
131-
</View>
132-
)}
133-
</View>
140+
<React.Fragment key={index}>
141+
{renderCell(cellValue, index, isFocused)}
142+
</React.Fragment>
134143
)}
135144
{...rest}
136145
/>
@@ -139,6 +148,9 @@ const PinInput = React.forwardRef<NativeTextInput, PinInputProps>(
139148
);
140149

141150
const styles = StyleSheet.create({
151+
rootContainer: {
152+
justifyContent: "center",
153+
},
142154
cell: {
143155
marginStart: 5,
144156
marginEnd: 5,
@@ -150,6 +162,7 @@ const styles = StyleSheet.create({
150162
maxWidth: 70,
151163
maxHeight: 70,
152164
borderWidth: 1,
165+
flex: 1,
153166
},
154167
cellText: {
155168
fontSize: 25,

0 commit comments

Comments
 (0)