Skip to content

Commit b48088a

Browse files
committed
Add checkbox component.
1 parent 47eb3d3 commit b48088a

File tree

5 files changed

+988
-0
lines changed

5 files changed

+988
-0
lines changed
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import * as React from "react";
2+
import { StyleSheet, View, Text, ViewStyle, TextStyle } from "react-native";
3+
import type { CheckboxStateStyle } from "../../types/CheckboxStateStyle";
4+
import type { CheckboxStyle } from "../../types/CheckboxStyle";
5+
import { Hitbox } from "../Hitbox";
6+
7+
const createViewStyle = (
8+
checkboxStyle: CheckboxStyle,
9+
checkboxStateStyle: CheckboxStateStyle
10+
): ViewStyle => {
11+
const output: ViewStyle = {
12+
backgroundColor: checkboxStateStyle.backgroundColor,
13+
width: checkboxStyle.boxSize,
14+
height: checkboxStyle.boxSize,
15+
justifyContent: `center`,
16+
alignItems: `center`,
17+
};
18+
19+
if (checkboxStateStyle.border !== null) {
20+
output.borderWidth = checkboxStateStyle.border.width;
21+
output.borderColor = checkboxStateStyle.border.color;
22+
}
23+
24+
if (checkboxStateStyle.radius !== 0) {
25+
output.borderRadius = checkboxStateStyle.radius;
26+
}
27+
28+
const relativeBorderWidth =
29+
(checkboxStyle.enabledFalse.border === null
30+
? 0
31+
: checkboxStyle.enabledFalse.border.width) -
32+
(checkboxStateStyle.border === null ? 0 : checkboxStateStyle.border.width);
33+
34+
if (relativeBorderWidth !== 0) {
35+
output.margin = relativeBorderWidth;
36+
}
37+
38+
return output;
39+
};
40+
41+
const createTextStyle = (
42+
checkboxStyle: CheckboxStyle,
43+
checkboxStateStyle: CheckboxStateStyle
44+
): TextStyle => {
45+
const output: TextStyle = {
46+
fontFamily: checkboxStyle.fontFamily,
47+
fontSize: checkboxStyle.fontSize,
48+
lineHeight: checkboxStyle.fontSize * 1.4,
49+
color: checkboxStateStyle.color,
50+
};
51+
52+
if (checkboxStyle.boxLabelSpacing !== 0) {
53+
output.paddingLeft = checkboxStyle.boxLabelSpacing;
54+
}
55+
56+
return output;
57+
};
58+
59+
/**
60+
* Creates a React component representing a form checkbox.
61+
* @param checkboxStyle The style to apply to the checkbox.
62+
* @returns The created React component.
63+
*/
64+
export const createCheckboxComponent = (
65+
checkboxStyle: CheckboxStyle
66+
): React.FunctionComponent<{
67+
/**
68+
* When true, the checkbox is checked. It is otherwise unchecked.
69+
*/
70+
value: boolean;
71+
72+
/**
73+
* Invoked when the checkbox is pressed.
74+
* @param to True when the checkbox is changing from unchecked to checked,
75+
* otherwise, false.
76+
*/
77+
onChange(to: boolean): void;
78+
79+
/**
80+
* When true, the checkbox will show alternative styles and will not accept
81+
* input. It will otherwise show its default styles and accept input.
82+
*/
83+
disabled: boolean;
84+
}> => {
85+
const styles = StyleSheet.create({
86+
hitbox: {
87+
width: `100%`,
88+
flexDirection: `row`,
89+
},
90+
disabledFalseView: createViewStyle(
91+
checkboxStyle,
92+
checkboxStyle.disabledFalse
93+
),
94+
disabledTrueView: createViewStyle(
95+
checkboxStyle,
96+
checkboxStyle.disabledTrue
97+
),
98+
enabledFalseView: createViewStyle(
99+
checkboxStyle,
100+
checkboxStyle.enabledFalse
101+
),
102+
enabledTrueView: createViewStyle(checkboxStyle, checkboxStyle.enabledTrue),
103+
disabledFalseText: createTextStyle(
104+
checkboxStyle,
105+
checkboxStyle.disabledFalse
106+
),
107+
disabledTrueText: createTextStyle(
108+
checkboxStyle,
109+
checkboxStyle.disabledTrue
110+
),
111+
enabledFalseText: createTextStyle(
112+
checkboxStyle,
113+
checkboxStyle.enabledFalse
114+
),
115+
enabledTrueText: createTextStyle(checkboxStyle, checkboxStyle.enabledTrue),
116+
});
117+
118+
return ({ value, onChange, disabled, children }) => (
119+
<Hitbox
120+
disabled={disabled}
121+
onPress={() => {
122+
onChange(!value);
123+
}}
124+
style={styles.hitbox}
125+
>
126+
<View
127+
style={
128+
value
129+
? disabled
130+
? styles.disabledTrueView
131+
: styles.enabledTrueView
132+
: disabled
133+
? styles.disabledFalseView
134+
: styles.enabledFalseView
135+
}
136+
>
137+
{value
138+
? disabled
139+
? checkboxStyle.disabledTrue.boxChild
140+
: checkboxStyle.enabledTrue.boxChild
141+
: disabled
142+
? checkboxStyle.disabledFalse.boxChild
143+
: checkboxStyle.enabledFalse.boxChild}
144+
</View>
145+
<Text
146+
style={
147+
value
148+
? disabled
149+
? styles.disabledTrueText
150+
: styles.enabledTrueText
151+
: disabled
152+
? styles.disabledFalseText
153+
: styles.enabledFalseText
154+
}
155+
>
156+
{children}
157+
</Text>
158+
</Hitbox>
159+
);
160+
};
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# `react-native-app-helpers/createCheckboxComponent`
2+
3+
Creates a React component representing a form checkbox.
4+
5+
## Usage
6+
7+
```tsx
8+
import { createCheckboxComponent } from "react-native-app-helpers";
9+
10+
const ExampleCheckbox = createCheckboxComponent({
11+
fontFamily: `Example Font Family`,
12+
fontSize: 16,
13+
boxSize: 14,
14+
boxLabelSpacing: 5,
15+
disabledFalse: {
16+
backgroundColor: 'blue',
17+
color: 'yellow',
18+
boxChild: <Text>DF</Text>,
19+
radius: 3,
20+
border: {
21+
width: 5,
22+
color: `red`,
23+
},
24+
},
25+
disabledTrue: {
26+
backgroundColor: 'blue',
27+
color: 'yellow',
28+
boxChild: <Text>DT</Text>,
29+
radius: 3,
30+
border: {
31+
width: 5,
32+
color: `red`,
33+
},
34+
},
35+
enabledFalse: {
36+
backgroundColor: 'blue',
37+
color: 'yellow',
38+
boxChild: <Text>EF</Text>,
39+
radius: 3,
40+
border: {
41+
width: 5,
42+
color: `red`,
43+
},
44+
},
45+
enabledTrue: {
46+
backgroundColor: 'blue',
47+
color: 'yellow',
48+
boxChild: <Text>ET</Text>,
49+
radius: 3,
50+
border: {
51+
width: 5,
52+
color: `red`,
53+
},
54+
},
55+
});
56+
57+
const ExampleScreen = () => {
58+
const [value, setValue] = React.useState(false);
59+
60+
return (
61+
<ExampleCheckbox value={value} onChange={setValue} disabled={false}>
62+
Example Label
63+
</ExampleCheckbox>
64+
);
65+
};
66+
```

0 commit comments

Comments
 (0)