react95-native-rabbl 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +24 -0
  3. package/package.json +154 -0
  4. package/src/assets/fonts/src/ms-sans-serif/MS Sans Serif.ttf +0 -0
  5. package/src/assets/fonts/src/ms-sans-serif/license.txt +4 -0
  6. package/src/assets/fonts/src/ms-sans-serif/readme.txt +26 -0
  7. package/src/assets/fonts/src/ms-sans-serif-bold/MS Sans Serif Bold.ttf +0 -0
  8. package/src/assets/fonts/src/ms-sans-serif-bold/license.txt +4 -0
  9. package/src/assets/fonts/src/ms-sans-serif-bold/readme.txt +26 -0
  10. package/src/components/AppBar/AppBar.spec.tsx +140 -0
  11. package/src/components/AppBar/AppBar.tsx +43 -0
  12. package/src/components/AppBar/AppBarBackAction.tsx +20 -0
  13. package/src/components/AppBar/AppBarContent.tsx +84 -0
  14. package/src/components/AppBar/index.ts +1 -0
  15. package/src/components/Button/Button.spec.tsx +59 -0
  16. package/src/components/Button/Button.tsx +236 -0
  17. package/src/components/Button/index.ts +1 -0
  18. package/src/components/Card/Card.spec.tsx +54 -0
  19. package/src/components/Card/Card.tsx +88 -0
  20. package/src/components/Card/CardContent.tsx +23 -0
  21. package/src/components/Card/index.ts +1 -0
  22. package/src/components/Checkbox/Checkbox.tsx +10 -0
  23. package/src/components/Checkbox/index.ts +1 -0
  24. package/src/components/ColorButton/ColorButton.tsx +69 -0
  25. package/src/components/ColorButton/index.ts +1 -0
  26. package/src/components/ColorPicker/ColorPicker.tsx +109 -0
  27. package/src/components/ColorPicker/index.ts +1 -0
  28. package/src/components/Desktop/Desktop.spec.tsx +32 -0
  29. package/src/components/Desktop/Desktop.tsx +132 -0
  30. package/src/components/Desktop/index.tsx +1 -0
  31. package/src/components/Divider/Divider.spec.tsx +47 -0
  32. package/src/components/Divider/Divider.tsx +52 -0
  33. package/src/components/Divider/index.tsx +1 -0
  34. package/src/components/FAB/FAB.tsx +288 -0
  35. package/src/components/FAB/FABGroup.tsx +385 -0
  36. package/src/components/FAB/index.ts +1 -0
  37. package/src/components/Fieldset/Fieldset.spec.tsx +48 -0
  38. package/src/components/Fieldset/Fieldset.tsx +107 -0
  39. package/src/components/Fieldset/index.ts +1 -0
  40. package/src/components/Hourglass/Hourglass.spec.tsx +24 -0
  41. package/src/components/Hourglass/Hourglass.tsx +43 -0
  42. package/src/components/Hourglass/base64hourglass.ts +3 -0
  43. package/src/components/Hourglass/index.ts +1 -0
  44. package/src/components/Icons/ArrowIcon.tsx +85 -0
  45. package/src/components/Icons/CheckmarkIcon.tsx +55 -0
  46. package/src/components/Icons/ChevronIcon.tsx +93 -0
  47. package/src/components/Icons/CloseIcon.tsx +48 -0
  48. package/src/components/Icons/index.ts +4 -0
  49. package/src/components/Label/Label.tsx +77 -0
  50. package/src/components/Label/index.ts +1 -0
  51. package/src/components/List/List.tsx +3 -0
  52. package/src/components/List/ListAccordion.tsx +154 -0
  53. package/src/components/List/ListItem.tsx +74 -0
  54. package/src/components/List/ListSection.tsx +51 -0
  55. package/src/components/List/index.ts +3 -0
  56. package/src/components/Menu/Menu.tsx +100 -0
  57. package/src/components/Menu/MenuItem.tsx +100 -0
  58. package/src/components/Menu/index.ts +1 -0
  59. package/src/components/NumberInput/NumberInput.spec.tsx +119 -0
  60. package/src/components/NumberInput/NumberInput.tsx +144 -0
  61. package/src/components/NumberInput/index.ts +1 -0
  62. package/src/components/Panel/Panel.spec.tsx +29 -0
  63. package/src/components/Panel/Panel.tsx +75 -0
  64. package/src/components/Panel/index.ts +1 -0
  65. package/src/components/Portal/Portal.tsx +52 -0
  66. package/src/components/Portal/PortalConsumer.tsx +48 -0
  67. package/src/components/Portal/PortalHost.tsx +150 -0
  68. package/src/components/Portal/PortalManager.tsx +57 -0
  69. package/src/components/Portal/index.ts +1 -0
  70. package/src/components/Progress/Progress.tsx +125 -0
  71. package/src/components/Progress/index.ts +1 -0
  72. package/src/components/Radio/Radio.tsx +14 -0
  73. package/src/components/Radio/index.ts +1 -0
  74. package/src/components/ScrollPanel/ScrollPanel.tsx +72 -0
  75. package/src/components/ScrollPanel/index.ts +1 -0
  76. package/src/components/ScrollView/ScrollView.tsx +284 -0
  77. package/src/components/ScrollView/index.ts +1 -0
  78. package/src/components/Select/Select.tsx +229 -0
  79. package/src/components/Select/SelectBase.tsx +119 -0
  80. package/src/components/Select/SelectBox.tsx +66 -0
  81. package/src/components/Select/index.ts +2 -0
  82. package/src/components/Slider/Slider.tsx +301 -0
  83. package/src/components/Slider/index.ts +1 -0
  84. package/src/components/Snackbar/Snackbar.tsx +260 -0
  85. package/src/components/Snackbar/SnackbarContent.tsx +23 -0
  86. package/src/components/Snackbar/index.ts +1 -0
  87. package/src/components/SwitchBase/SwitchBase.tsx +193 -0
  88. package/src/components/SwitchBase/index.ts +1 -0
  89. package/src/components/Tabs/Tabs.tsx +208 -0
  90. package/src/components/Tabs/index.ts +1 -0
  91. package/src/components/TextInput/TextInput.tsx +82 -0
  92. package/src/components/TextInput/index.ts +1 -0
  93. package/src/components/Toolbar/Toolbar.tsx +113 -0
  94. package/src/components/Toolbar/index.ts +1 -0
  95. package/src/components/Typography/Anchor.tsx +38 -0
  96. package/src/components/Typography/Text.spec.tsx +30 -0
  97. package/src/components/Typography/Text.tsx +55 -0
  98. package/src/components/Typography/Title.tsx +58 -0
  99. package/src/components/Typography/index.ts +3 -0
  100. package/src/components/Window/Window.tsx +132 -0
  101. package/src/components/Window/index.ts +1 -0
  102. package/src/core/Provider.tsx +52 -0
  103. package/src/core/theming.tsx +8 -0
  104. package/src/hooks/useAsyncReference.ts +22 -0
  105. package/src/hooks/useControlledOrUncontrolled.ts +23 -0
  106. package/src/index.ts +38 -0
  107. package/src/styles/shadow.tsx +36 -0
  108. package/src/styles/styleElements.tsx +105 -0
  109. package/src/styles/styles.ts +129 -0
  110. package/src/styles/themes/aiee.ts +36 -0
  111. package/src/styles/themes/ash.ts +35 -0
  112. package/src/styles/themes/azureOrange.ts +33 -0
  113. package/src/styles/themes/bee.ts +33 -0
  114. package/src/styles/themes/blackAndWhite.ts +33 -0
  115. package/src/styles/themes/blue.ts +36 -0
  116. package/src/styles/themes/brick.ts +33 -0
  117. package/src/styles/themes/candy.ts +33 -0
  118. package/src/styles/themes/cherry.ts +36 -0
  119. package/src/styles/themes/coldGray.ts +34 -0
  120. package/src/styles/themes/counterStrike.ts +33 -0
  121. package/src/styles/themes/darkTeal.ts +36 -0
  122. package/src/styles/themes/eggplant.ts +33 -0
  123. package/src/styles/themes/fxDev.ts +36 -0
  124. package/src/styles/themes/highContrast.ts +33 -0
  125. package/src/styles/themes/hotChocolate.ts +36 -0
  126. package/src/styles/themes/index.ts +103 -0
  127. package/src/styles/themes/lilac.ts +33 -0
  128. package/src/styles/themes/lilacRoseDark.ts +34 -0
  129. package/src/styles/themes/maple.ts +33 -0
  130. package/src/styles/themes/marine.ts +33 -0
  131. package/src/styles/themes/matrix.ts +33 -0
  132. package/src/styles/themes/millenium.ts +33 -0
  133. package/src/styles/themes/modernDark.ts +33 -0
  134. package/src/styles/themes/molecule.ts +33 -0
  135. package/src/styles/themes/monochrome.ts +0 -0
  136. package/src/styles/themes/ninjaTurtles.ts +33 -0
  137. package/src/styles/themes/olive.ts +33 -0
  138. package/src/styles/themes/original.ts +33 -0
  139. package/src/styles/themes/pamelaAnderson.ts +33 -0
  140. package/src/styles/themes/plum.ts +33 -0
  141. package/src/styles/themes/polarized.ts +36 -0
  142. package/src/styles/themes/powerShell.ts +36 -0
  143. package/src/styles/themes/rainyDay.ts +33 -0
  144. package/src/styles/themes/raspberry.ts +36 -0
  145. package/src/styles/themes/redWine.ts +36 -0
  146. package/src/styles/themes/rose.ts +33 -0
  147. package/src/styles/themes/seawater.ts +36 -0
  148. package/src/styles/themes/slate.ts +33 -0
  149. package/src/styles/themes/solarizedDark.ts +36 -0
  150. package/src/styles/themes/solarizedLight.ts +36 -0
  151. package/src/styles/themes/spruce.ts +33 -0
  152. package/src/styles/themes/stormClouds.ts +36 -0
  153. package/src/styles/themes/theSixtiesUSA.ts +33 -0
  154. package/src/styles/themes/tokyoDark.ts +33 -0
  155. package/src/styles/themes/tooSexy.ts +33 -0
  156. package/src/styles/themes/travel.ts +33 -0
  157. package/src/styles/themes/vaporTeal.ts +33 -0
  158. package/src/styles/themes/vermillion.ts +33 -0
  159. package/src/styles/themes/violetDark.ts +33 -0
  160. package/src/styles/themes/water.ts +33 -0
  161. package/src/styles/themes/wmii.ts +36 -0
  162. package/src/types.tsx +55 -0
  163. package/src/utils/index.ts +57 -0
@@ -0,0 +1,85 @@
1
+ import React from 'react';
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3
+
4
+ import { withTheme } from '../../core/theming';
5
+ import type { Direction, Color, Theme } from '../../types';
6
+
7
+ type Props = {
8
+ color?: Color;
9
+ direction?: Direction;
10
+ disabled?: boolean;
11
+ segments?: number;
12
+ shadowOffset?: number;
13
+ style?: StyleProp<ViewStyle>;
14
+ theme: Theme;
15
+ };
16
+
17
+ const pixelSize = 2;
18
+
19
+ const ArrowIcon = ({
20
+ color,
21
+ direction = 'down',
22
+ disabled = false,
23
+ segments = 4,
24
+ shadowOffset,
25
+ style = {},
26
+ theme,
27
+ ...rest
28
+ }: Props) => {
29
+ const segmentSizes = new Array(segments).fill(null).map((_, i) => 1 + i * 2);
30
+
31
+ if (['right', 'down'].includes(direction)) {
32
+ segmentSizes.reverse();
33
+ }
34
+ const isHorizontal = ['left', 'right'].includes(direction);
35
+
36
+ return (
37
+ <View
38
+ style={[
39
+ styles.wrapper,
40
+ {
41
+ flexDirection: isHorizontal ? 'row' : 'column',
42
+ },
43
+ style,
44
+ ]}
45
+ {...rest}
46
+ >
47
+ {segmentSizes.map((segmentSize, i) => (
48
+ <View
49
+ key={i}
50
+ style={[
51
+ styles.segment,
52
+ {
53
+ [isHorizontal ? 'height' : 'width']: pixelSize * segmentSize,
54
+ [isHorizontal ? 'width' : 'height']: pixelSize,
55
+ backgroundColor:
56
+ color ||
57
+ (disabled ? theme.materialTextDisabled : theme.materialText),
58
+ shadowColor: disabled
59
+ ? theme.materialTextDisabledShadow
60
+ : 'transparent',
61
+ shadowOffset: {
62
+ width: shadowOffset || pixelSize,
63
+ height: shadowOffset || pixelSize,
64
+ },
65
+ shadowOpacity: 1,
66
+ shadowRadius: 0,
67
+ },
68
+ ]}
69
+ />
70
+ ))}
71
+ </View>
72
+ );
73
+ };
74
+
75
+ const styles = StyleSheet.create({
76
+ wrapper: {
77
+ position: 'relative',
78
+ alignItems: 'center',
79
+ },
80
+ segment: {
81
+ height: pixelSize,
82
+ },
83
+ });
84
+
85
+ export default withTheme(ArrowIcon);
@@ -0,0 +1,55 @@
1
+ import React from 'react';
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3
+
4
+ import type { Theme } from '../../types';
5
+ import { withTheme } from '../../core/theming';
6
+
7
+ type Props = {
8
+ disabled?: boolean;
9
+ style?: StyleProp<ViewStyle>;
10
+ theme: Theme;
11
+ };
12
+
13
+ const pixelSize = 1.5;
14
+ const segmentSize = 3 * pixelSize;
15
+
16
+ const CheckmarkIcon = ({
17
+ disabled = false,
18
+ style = {},
19
+ theme,
20
+ ...rest
21
+ }: Props) => {
22
+ const segmentOffsets = [2, 3, 4, 3, 2, 1, 0];
23
+
24
+ return (
25
+ <View style={[styles.wrapper, style]} {...rest}>
26
+ {segmentOffsets.map((offset, i) => (
27
+ <View
28
+ key={i}
29
+ style={[
30
+ styles.segment,
31
+ {
32
+ marginTop: offset * pixelSize,
33
+ backgroundColor: disabled
34
+ ? theme.checkmarkDisabled
35
+ : theme.checkmark,
36
+ },
37
+ ]}
38
+ />
39
+ ))}
40
+ </View>
41
+ );
42
+ };
43
+
44
+ const styles = StyleSheet.create({
45
+ wrapper: {
46
+ position: 'relative',
47
+ flexDirection: 'row',
48
+ },
49
+ segment: {
50
+ width: pixelSize,
51
+ height: segmentSize,
52
+ },
53
+ });
54
+
55
+ export default withTheme(CheckmarkIcon);
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3
+
4
+ import { withTheme } from '../../core/theming';
5
+
6
+ import type { Color, Direction, Theme } from '../../types';
7
+
8
+ type Props = {
9
+ color?: Color;
10
+ direction?: Direction;
11
+ disabled?: boolean;
12
+ segments?: number;
13
+ style?: StyleProp<ViewStyle>;
14
+ theme: Theme;
15
+ };
16
+
17
+ const pixelSize = 2;
18
+
19
+ const ChevronIcon = ({
20
+ color,
21
+ direction = 'down',
22
+ disabled = false,
23
+ segments = 5,
24
+ style = {},
25
+ theme,
26
+ ...rest
27
+ }: Props) => {
28
+ const baseColor = color || theme.materialText;
29
+ let segmentSizes = new Array(segments).fill(null).map((_, i) => 1 + i * 2);
30
+
31
+ if (['right', 'down'].includes(direction)) {
32
+ segmentSizes = segmentSizes.reverse();
33
+ }
34
+ const isHorizontal = ['left', 'right'].includes(direction);
35
+
36
+ const SegmentPixel = () => (
37
+ <View
38
+ style={{
39
+ [isHorizontal ? 'width' : 'height']: pixelSize * 2,
40
+ [isHorizontal ? 'height' : 'width']: pixelSize,
41
+ backgroundColor: disabled ? theme.materialTextDisabled : baseColor,
42
+ shadowColor: disabled
43
+ ? theme.materialTextDisabledShadow
44
+ : 'transparent',
45
+ shadowOffset: {
46
+ width: pixelSize,
47
+ height: pixelSize,
48
+ },
49
+ shadowOpacity: 1,
50
+ shadowRadius: 0,
51
+ }}
52
+ />
53
+ );
54
+
55
+ return (
56
+ <View
57
+ style={[
58
+ styles.wrapper,
59
+ {
60
+ flexDirection: isHorizontal ? 'row' : 'column',
61
+ },
62
+ style,
63
+ ]}
64
+ {...rest}
65
+ >
66
+ {segmentSizes.map((segmentSize, i) => (
67
+ <View
68
+ key={i}
69
+ style={[
70
+ {
71
+ [isHorizontal ? 'height' : 'width']: pixelSize * segmentSize,
72
+ [isHorizontal ? 'width' : 'height']: pixelSize,
73
+ flexDirection: isHorizontal ? 'column' : 'row',
74
+ justifyContent: 'space-between',
75
+ },
76
+ ]}
77
+ >
78
+ {segmentSize !== 1 && <SegmentPixel />}
79
+ <SegmentPixel />
80
+ </View>
81
+ ))}
82
+ </View>
83
+ );
84
+ };
85
+
86
+ const styles = StyleSheet.create({
87
+ wrapper: {
88
+ position: 'relative',
89
+ alignItems: 'center',
90
+ },
91
+ });
92
+
93
+ export default withTheme(ChevronIcon);
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
3
+
4
+ import type { Theme } from '../../types';
5
+ import { withTheme } from '../../core/theming';
6
+ import { ChevronIcon } from '../..';
7
+
8
+ type Props = {
9
+ disabled?: boolean;
10
+ segments?: number;
11
+ style?: StyleProp<ViewStyle>;
12
+ theme: Theme;
13
+ };
14
+
15
+ const CloseIcon = ({
16
+ disabled = false,
17
+ segments = 4,
18
+ style,
19
+ theme,
20
+ ...rest
21
+ }: Props) => {
22
+ return (
23
+ <View style={[styles.wrapper, style]} {...rest}>
24
+ <ChevronIcon
25
+ theme={theme}
26
+ disabled={disabled}
27
+ segments={segments}
28
+ direction='right'
29
+ />
30
+ <ChevronIcon
31
+ theme={theme}
32
+ disabled={disabled}
33
+ segments={segments}
34
+ direction='left'
35
+ style={{ marginLeft: -2, marginRight: 2 }}
36
+ />
37
+ </View>
38
+ );
39
+ };
40
+
41
+ const styles = StyleSheet.create({
42
+ wrapper: {
43
+ alignItems: 'center',
44
+ flexDirection: 'row',
45
+ },
46
+ });
47
+
48
+ export default withTheme(CloseIcon);
@@ -0,0 +1,4 @@
1
+ export { default as ArrowIcon } from './ArrowIcon';
2
+ export { default as ChevronIcon } from './ChevronIcon';
3
+ export { default as CheckmarkIcon } from './CheckmarkIcon';
4
+ export { default as CloseIcon } from './CloseIcon';
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import {
3
+ StyleProp,
4
+ StyleSheet,
5
+ Animated,
6
+ View,
7
+ ViewStyle,
8
+ TouchableWithoutFeedback,
9
+ } from 'react-native';
10
+
11
+ import { withTheme } from '../../core/theming';
12
+ import shadow from '../../styles/shadow';
13
+ import type { Theme } from '../../types';
14
+
15
+ import { Text } from '../..';
16
+
17
+ type Props = React.ComponentPropsWithRef<typeof View> & {
18
+ accessible?: boolean;
19
+ children?: React.ReactNode;
20
+ elevation?: number;
21
+ onLongPress?: () => void;
22
+ onPress?: () => void;
23
+ radius?: number;
24
+ style?: StyleProp<ViewStyle>;
25
+ theme: Theme;
26
+ };
27
+
28
+ const Label = ({
29
+ accessible,
30
+ children,
31
+ elevation = 0,
32
+ onLongPress,
33
+ onPress,
34
+ radius = 4,
35
+ style = {},
36
+ theme,
37
+ ...rest
38
+ }: Props) => {
39
+ return (
40
+ // TODO: fix this TS error
41
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
+ // @ts-ignore
43
+ <Animated.View
44
+ {...rest}
45
+ style={[
46
+ styles.container,
47
+ {
48
+ backgroundColor: theme.tooltip,
49
+ borderRadius: radius,
50
+ },
51
+ shadow(elevation),
52
+ style,
53
+ ]}
54
+ >
55
+ <TouchableWithoutFeedback
56
+ delayPressIn={0}
57
+ disabled={!(onPress || onLongPress)}
58
+ onLongPress={onLongPress}
59
+ onPress={onPress}
60
+ accessible={accessible}
61
+ >
62
+ <Text>{children}</Text>
63
+ </TouchableWithoutFeedback>
64
+ </Animated.View>
65
+ );
66
+ };
67
+
68
+ const styles = StyleSheet.create({
69
+ container: {
70
+ position: 'relative',
71
+ borderWidth: 2,
72
+ paddingHorizontal: 12,
73
+ paddingVertical: 6,
74
+ },
75
+ });
76
+
77
+ export default withTheme(Label);
@@ -0,0 +1 @@
1
+ export { default } from './Label';
@@ -0,0 +1,3 @@
1
+ export { default as Section } from './ListSection';
2
+ export { default as Accordion, Divider } from './ListAccordion';
3
+ export { default as Item } from './ListItem';
@@ -0,0 +1,154 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ ViewStyle,
5
+ StyleSheet,
6
+ StyleProp,
7
+ TextStyle,
8
+ TouchableHighlight,
9
+ } from 'react-native';
10
+
11
+ import type { Theme } from '../../types';
12
+ import { withTheme } from '../../core/theming';
13
+
14
+ import { Text, ChevronIcon } from '../..';
15
+ import { blockSizes } from '../../styles/styles';
16
+ import useControlledOrUncontrolled from '../../hooks/useControlledOrUncontrolled';
17
+
18
+ // TODO: create LinkButton component that will have link colour that will serve as a clickable List.Item
19
+
20
+ type Props = React.ComponentPropsWithRef<typeof View> & {
21
+ children: React.ReactNode;
22
+ defaultExpanded?: boolean;
23
+ expanded?: boolean;
24
+ onPress?: () => void;
25
+ style?: StyleProp<ViewStyle>;
26
+ subtitle?: string;
27
+ subtitleStyle?: StyleProp<TextStyle>;
28
+ theme: Theme;
29
+ title?: string;
30
+ titleStyle?: StyleProp<TextStyle>;
31
+ };
32
+
33
+ // TODO: add accessibilityState=expanded ?
34
+ const ListAccordion = ({
35
+ children,
36
+ defaultExpanded,
37
+ expanded: expandedProp,
38
+ onPress,
39
+ style,
40
+ subtitle,
41
+ subtitleStyle,
42
+ theme,
43
+ title,
44
+ titleStyle,
45
+ ...rest
46
+ }: Props) => {
47
+ const [expanded, setExpanded] = useControlledOrUncontrolled({
48
+ value: expandedProp,
49
+ defaultValue: defaultExpanded,
50
+ });
51
+
52
+ const handlePress = () => {
53
+ onPress?.();
54
+
55
+ if (expandedProp === undefined) {
56
+ setExpanded((currentExpanded: boolean) => !currentExpanded);
57
+ }
58
+ };
59
+
60
+ return (
61
+ <View
62
+ {...rest}
63
+ style={[styles.wrapper, { borderColor: theme.flatLight }, style]}
64
+ >
65
+ <TouchableHighlight onPress={handlePress} accessibilityRole='button'>
66
+ <View
67
+ style={[styles.header, { backgroundColor: theme.flatLight }]}
68
+ pointerEvents='none'
69
+ >
70
+ <View>
71
+ {title && (
72
+ <Text
73
+ bold
74
+ style={[styles.title, { color: theme.progress }, titleStyle]}
75
+ >
76
+ {title}
77
+ </Text>
78
+ )}
79
+ {subtitle && (
80
+ <Text secondary style={[styles.subtitle, subtitleStyle]}>
81
+ {subtitle}
82
+ </Text>
83
+ )}
84
+ </View>
85
+ <View style={styles.expandIcon}>
86
+ <ChevronIcon
87
+ theme={theme}
88
+ color={theme.progress}
89
+ segments={3}
90
+ direction={expanded ? 'up' : 'down'}
91
+ />
92
+ <ChevronIcon
93
+ theme={theme}
94
+ color={theme.progress}
95
+ segments={3}
96
+ style={{ marginVertical: 1 }}
97
+ direction={expanded ? 'up' : 'down'}
98
+ />
99
+ </View>
100
+ </View>
101
+ </TouchableHighlight>
102
+ {expanded && <View style={[styles.body]}>{children}</View>}
103
+ </View>
104
+ );
105
+ };
106
+
107
+ // TODO: do we need 'displayName' ?
108
+ // ListAccordion.displayName = 'List.Accordion';
109
+
110
+ const styles = StyleSheet.create({
111
+ wrapper: {
112
+ borderWidth: 2,
113
+ },
114
+ header: {
115
+ paddingVertical: 4,
116
+ paddingHorizontal: 8,
117
+ minHeight: blockSizes.md,
118
+ justifyContent: 'space-between',
119
+ alignItems: 'center',
120
+ display: 'flex',
121
+ flexDirection: 'row',
122
+ },
123
+ title: {
124
+ // TODO: create separate color variable for this? or should we use theme.materialColor instead?
125
+ },
126
+ subtitle: {
127
+ // TODO: make a Text component with standarized font sizes where normal is 16 / small 13 ...etc
128
+ fontSize: 13,
129
+ marginTop: 4,
130
+ },
131
+ expandIcon: {
132
+ marginRight: 4,
133
+ },
134
+ body: {},
135
+ divider: {
136
+ height: 2,
137
+ width: 'auto',
138
+ },
139
+ });
140
+
141
+ type DividerProps = {
142
+ theme: Theme;
143
+ };
144
+
145
+ const Divider = ({ theme }: DividerProps) => {
146
+ return (
147
+ <View style={[styles.divider, { backgroundColor: theme.flatLight }]} />
148
+ );
149
+ };
150
+
151
+ const DividerWithTheme = withTheme(Divider);
152
+
153
+ export { DividerWithTheme as Divider };
154
+ export default withTheme(ListAccordion);
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ ViewStyle,
5
+ StyleSheet,
6
+ StyleProp,
7
+ TextStyle,
8
+ TouchableOpacity,
9
+ } from 'react-native';
10
+
11
+ import type { Theme } from '../../types';
12
+ import { withTheme } from '../../core/theming';
13
+
14
+ import { blockSizes } from '../../styles/styles';
15
+
16
+ import { Text } from '../..';
17
+
18
+ type Props = React.ComponentPropsWithRef<typeof View> & {
19
+ left?: React.ReactNode;
20
+ onPress?: () => void;
21
+ right?: React.ReactNode;
22
+ style?: StyleProp<ViewStyle>;
23
+ theme: Theme;
24
+ title?: string;
25
+ titleStyle?: StyleProp<TextStyle>;
26
+ };
27
+
28
+ const ListItem = ({
29
+ left,
30
+ onPress,
31
+ right,
32
+ style,
33
+ theme,
34
+ title,
35
+ titleStyle,
36
+ ...rest
37
+ }: Props) => {
38
+ return (
39
+ <View style={style} {...rest}>
40
+ <TouchableOpacity onPress={onPress} accessibilityRole='button'>
41
+ <View style={[styles.content]}>
42
+ {left && <View style={[styles.left]}>{left}</View>}
43
+ {title && (
44
+ <Text style={[styles.title, { color: theme.progress }, titleStyle]}>
45
+ {title}
46
+ </Text>
47
+ )}
48
+ {right && <View style={[styles.right]}>{right}</View>}
49
+ </View>
50
+ </TouchableOpacity>
51
+ </View>
52
+ );
53
+ };
54
+
55
+ const styles = StyleSheet.create({
56
+ content: {
57
+ display: 'flex',
58
+ flexDirection: 'row',
59
+ alignItems: 'center',
60
+ minHeight: blockSizes.md,
61
+ paddingVertical: 4,
62
+ },
63
+ title: {
64
+ fontSize: 16,
65
+ },
66
+ left: {
67
+ marginRight: 8,
68
+ },
69
+ right: {
70
+ marginLeft: 8,
71
+ },
72
+ });
73
+
74
+ export default withTheme(ListItem);
@@ -0,0 +1,51 @@
1
+ import * as React from 'react';
2
+ import {
3
+ View,
4
+ ViewStyle,
5
+ StyleSheet,
6
+ StyleProp,
7
+ TextStyle,
8
+ } from 'react-native';
9
+
10
+ import type { Theme } from '../../types';
11
+ import { withTheme } from '../../core/theming';
12
+
13
+ import { Text } from '../..';
14
+
15
+ type Props = React.ComponentPropsWithRef<typeof View> & {
16
+ children: React.ReactNode;
17
+ style?: StyleProp<ViewStyle>;
18
+ theme: Theme;
19
+ title?: string;
20
+ titleStyle?: StyleProp<TextStyle>;
21
+ };
22
+
23
+ const ListSection = ({
24
+ children,
25
+ style,
26
+ theme,
27
+ title,
28
+ titleStyle,
29
+ ...rest
30
+ }: Props) => (
31
+ <View {...rest} style={[styles.container, style]}>
32
+ {title && (
33
+ <Text theme={theme} bold secondary style={[styles.title, titleStyle]}>
34
+ {title}
35
+ </Text>
36
+ )}
37
+ {children}
38
+ </View>
39
+ );
40
+
41
+ const styles = StyleSheet.create({
42
+ container: {
43
+ padding: 8,
44
+ },
45
+ title: {
46
+ fontSize: 13,
47
+ marginVertical: 8,
48
+ },
49
+ });
50
+
51
+ export default withTheme(ListSection);
@@ -0,0 +1,3 @@
1
+ import * as List from './List';
2
+
3
+ export default List;