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,55 @@
1
+ import React from 'react';
2
+ import { Text as NativeText, StyleProp, TextStyle } from 'react-native';
3
+
4
+ import { withTheme } from '../../core/theming';
5
+ import { builtTextStyles } from '../../styles/styles';
6
+ import type { Theme } from '../../types';
7
+
8
+ export type TextProps = React.ComponentProps<typeof NativeText> & {
9
+ bold?: boolean;
10
+ children: React.ReactNode;
11
+ disabled?: boolean;
12
+ secondary?: boolean;
13
+ style?: StyleProp<TextStyle>;
14
+ theme: Theme;
15
+ };
16
+
17
+ // TODO: set proper lineHeight and make it so that it automatically adjusts for every fontSize
18
+ const Text = ({
19
+ bold = false,
20
+ children,
21
+ disabled = false,
22
+ secondary = false,
23
+ theme,
24
+ style,
25
+ ...rest
26
+ }: TextProps) => {
27
+ const textStyles = builtTextStyles(theme);
28
+
29
+ const getTextStyle = () => {
30
+ if (disabled) {
31
+ return textStyles.disabled;
32
+ }
33
+
34
+ if (secondary) {
35
+ return textStyles.secondary;
36
+ }
37
+
38
+ return textStyles.default;
39
+ };
40
+
41
+ return (
42
+ <NativeText
43
+ style={[
44
+ bold ? textStyles.bold : textStyles.regular,
45
+ getTextStyle(),
46
+ style,
47
+ ]}
48
+ {...rest}
49
+ >
50
+ {children}
51
+ </NativeText>
52
+ );
53
+ };
54
+
55
+ export default withTheme(Text);
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import { StyleSheet, View } from 'react-native';
3
+
4
+ import type { Theme } from '../../types';
5
+ import { withTheme } from '../../core/theming';
6
+
7
+ import { Divider } from '../..';
8
+ import Text, { TextProps } from './Text';
9
+
10
+ type Props = TextProps & {
11
+ align?: 'center' | 'left' | 'right';
12
+ theme: Theme;
13
+ };
14
+
15
+ const Title = ({ align = 'center', children, theme, ...rest }: Props) => {
16
+ const getAlignment = () => {
17
+ switch (align) {
18
+ case 'left':
19
+ return 'flex-start';
20
+ case 'right':
21
+ return 'flex-end';
22
+ default:
23
+ return 'center';
24
+ }
25
+ };
26
+
27
+ return (
28
+ <View style={[styles.wrapper]}>
29
+ <Divider style={[styles.divider]} />
30
+ <View
31
+ style={{
32
+ paddingLeft: align !== 'left' ? 8 : 0,
33
+ paddingRight: align !== 'right' ? 8 : 0,
34
+ backgroundColor: theme.material,
35
+ alignSelf: getAlignment(),
36
+ }}
37
+ >
38
+ <Text {...rest}>{children}</Text>
39
+ </View>
40
+ </View>
41
+ );
42
+ };
43
+
44
+ const styles = StyleSheet.create({
45
+ wrapper: {
46
+ position: 'relative',
47
+ width: '100%',
48
+ },
49
+ divider: {
50
+ position: 'absolute',
51
+ left: 0,
52
+ right: 0,
53
+ top: '50%',
54
+ transform: [{ translateY: -1 }],
55
+ },
56
+ });
57
+
58
+ export default withTheme(Title);
@@ -0,0 +1,3 @@
1
+ export { default as Text } from './Text';
2
+ export { default as Title } from './Title';
3
+ export { default as Anchor } from './Anchor';
@@ -0,0 +1,132 @@
1
+ import React from 'react';
2
+ import { StyleSheet, View, StyleProp, ViewStyle } from 'react-native';
3
+
4
+ import type { Theme } from '../../types';
5
+ import { withTheme } from '../../core/theming';
6
+
7
+ import { Panel, Button, Text, CloseIcon } from '../..';
8
+
9
+ type Props = React.ComponentPropsWithRef<typeof View> & {
10
+ // TODO: allow for inserting custom buttons to title bar?
11
+ active?: boolean;
12
+ children?: React.ReactNode;
13
+ onClose?: () => void;
14
+ onMaximize?: () => void;
15
+ onMinimize?: () => void;
16
+ style?: StyleProp<ViewStyle>;
17
+ theme: Theme;
18
+ title?: string;
19
+ };
20
+
21
+ const Window = ({
22
+ active = true,
23
+ children,
24
+ onClose,
25
+ onMaximize,
26
+ onMinimize,
27
+ style = {},
28
+ theme,
29
+ title = '',
30
+ ...rest
31
+ }: Props) => {
32
+ return (
33
+ <Panel
34
+ theme={theme}
35
+ variant='raised'
36
+ elevation={4}
37
+ style={[styles.window, { backgroundColor: theme.material }, style]}
38
+ {...rest}
39
+ >
40
+ <View
41
+ style={[
42
+ styles.titleBar,
43
+ styles.flex,
44
+ {
45
+ backgroundColor: active
46
+ ? theme.headerBackground
47
+ : theme.headerNotActiveBackground,
48
+ },
49
+ ]}
50
+ >
51
+ <View style={[styles.flex]}>
52
+ <Text
53
+ theme={theme}
54
+ bold
55
+ // TODO: truncate window title when window is really small
56
+ ellipsizeMode='tail'
57
+ numberOfLines={1}
58
+ style={[
59
+ styles.titleBarText,
60
+ { color: active ? theme.headerText : theme.headerNotActiveText },
61
+ ]}
62
+ >
63
+ {title}
64
+ </Text>
65
+ </View>
66
+
67
+ <View style={[styles.flex]}>
68
+ <View style={[styles.flex, styles.buttonGroup]}>
69
+ {onMinimize && (
70
+ <Button
71
+ theme={theme}
72
+ onPress={onMinimize}
73
+ style={[styles.button]}
74
+ >
75
+ _
76
+ </Button>
77
+ )}
78
+ {onMaximize && (
79
+ <Button
80
+ theme={theme}
81
+ onPress={onMaximize}
82
+ style={[styles.button]}
83
+ >
84
+ []
85
+ </Button>
86
+ )}
87
+ </View>
88
+ {onClose && (
89
+ <Button theme={theme} onPress={onClose} style={[styles.button]}>
90
+ <CloseIcon />
91
+ </Button>
92
+ )}
93
+ </View>
94
+ </View>
95
+ {children}
96
+ </Panel>
97
+ );
98
+ };
99
+
100
+ const styles = StyleSheet.create({
101
+ flex: {
102
+ display: 'flex',
103
+ flexDirection: 'row',
104
+ justifyContent: 'space-between',
105
+ alignContent: 'center',
106
+ alignItems: 'center',
107
+ },
108
+ window: {
109
+ position: 'relative',
110
+ paddingVertical: 6,
111
+ paddingHorizontal: 6,
112
+ },
113
+ titleBar: {
114
+ height: 36,
115
+ margin: 2,
116
+ paddingRight: 4,
117
+ paddingLeft: 8,
118
+ },
119
+ titleBarText: {
120
+ flexShrink: 1,
121
+ },
122
+ buttonGroup: {
123
+ marginRight: 6,
124
+ },
125
+ button: {
126
+ height: 28,
127
+ width: 32,
128
+ padding: 0,
129
+ },
130
+ });
131
+
132
+ export default withTheme(Window);
@@ -0,0 +1 @@
1
+ export { default } from './Window';
@@ -0,0 +1,52 @@
1
+ /* eslint-disable react/destructuring-assignment */
2
+ import * as React from 'react';
3
+ // import { AccessibilityInfo } from 'react-native';
4
+ import { ThemeProvider } from './theming';
5
+ import PortalHost from '../components/Portal/PortalHost';
6
+
7
+ import original from '../styles/themes/original';
8
+
9
+ import type { Theme } from '../types';
10
+
11
+ type Props = {
12
+ children: React.ReactNode;
13
+ theme?: Theme;
14
+ };
15
+
16
+ const Provider = ({ ...props }: Props) => {
17
+ // const [reduceMotionEnabled, setReduceMotionEnabled] = React.useState<boolean>(
18
+ // false,
19
+ // );
20
+
21
+ // React.useEffect(() => {
22
+ // if (!props.theme) {
23
+ // AccessibilityInfo.addEventListener(
24
+ // 'reduceMotionChanged',
25
+ // setReduceMotionEnabled,
26
+ // );
27
+ // }
28
+ // return () => {
29
+ // if (!props.theme) {
30
+ // AccessibilityInfo.removeEventListener(
31
+ // 'reduceMotionChanged',
32
+ // setReduceMotionEnabled,
33
+ // );
34
+ // }
35
+ // };
36
+ // }, [props.theme]);
37
+
38
+ const getTheme = () => {
39
+ const { theme: providedTheme } = props;
40
+
41
+ return providedTheme || original;
42
+ };
43
+
44
+ const { children } = props;
45
+ return (
46
+ <PortalHost>
47
+ <ThemeProvider theme={getTheme()}>{children}</ThemeProvider>
48
+ </PortalHost>
49
+ );
50
+ };
51
+
52
+ export default Provider;
@@ -0,0 +1,8 @@
1
+ import { createTheming } from '@callstack/react-theme-provider';
2
+
3
+ import type { Theme } from '../types';
4
+ import original from '../styles/themes/original';
5
+
6
+ export const { ThemeProvider, withTheme, useTheme } = createTheming<Theme>(
7
+ original as Theme,
8
+ );
@@ -0,0 +1,22 @@
1
+ import React, { useState, useRef } from 'react';
2
+ import type { AnyValue } from '../types';
3
+
4
+ interface UpdateStateFunction extends Function {
5
+ (n: AnyValue): void;
6
+ }
7
+
8
+ export default function useAsyncReference(
9
+ value: AnyValue,
10
+ ): [React.RefObject<AnyValue>, UpdateStateFunction] {
11
+ const ref = useRef(value);
12
+ const [, rerender] = useState(false);
13
+
14
+ function updateState(newState: UpdateStateFunction) {
15
+ if (!Object.is(ref.current, newState)) {
16
+ ref.current = newState;
17
+ rerender(s => !s);
18
+ }
19
+ }
20
+
21
+ return [ref, updateState];
22
+ }
@@ -0,0 +1,23 @@
1
+ import { useState, useCallback } from 'react';
2
+ import type { AnyValue } from '../types';
3
+
4
+ type Props = {
5
+ value: AnyValue;
6
+ defaultValue: AnyValue;
7
+ };
8
+
9
+ export default ({
10
+ value,
11
+ defaultValue,
12
+ }: Props): [AnyValue, (newValue: AnyValue) => void] => {
13
+ const isControlled = value !== undefined;
14
+ const [controlledValue, setControlledValue] = useState(defaultValue);
15
+
16
+ const handleChangeIfUncontrolled = useCallback(newValue => {
17
+ if (!isControlled) {
18
+ setControlledValue(newValue);
19
+ }
20
+ }, []);
21
+
22
+ return [isControlled ? value : controlledValue, handleChangeIfUncontrolled];
23
+ };
package/src/index.ts ADDED
@@ -0,0 +1,38 @@
1
+ export { default as AppBar } from './components/AppBar';
2
+ export { default as Button } from './components/Button';
3
+ export { default as Card } from './components/Card';
4
+ export { default as Checkbox } from './components/Checkbox';
5
+ export { default as ColorButton } from './components/ColorButton';
6
+ export { default as ColorPicker } from './components/ColorPicker';
7
+ export { default as Desktop } from './components/Desktop';
8
+ export { default as Divider } from './components/Divider';
9
+ export { default as FAB } from './components/FAB';
10
+ export { default as Fieldset } from './components/Fieldset';
11
+ export { default as Hourglass } from './components/Hourglass';
12
+ export { default as Label } from './components/Label';
13
+ export { default as List } from './components/List';
14
+ export { default as Menu } from './components/Menu';
15
+ export { default as NumberInput } from './components/NumberInput';
16
+ export { default as Panel } from './components/Panel';
17
+ export { default as Portal } from './components/Portal';
18
+ export { default as Progress } from './components/Progress';
19
+ export { default as Radio } from './components/Radio';
20
+ export { default as ScrollPanel } from './components/ScrollPanel';
21
+ export { default as ScrollView } from './components/ScrollView';
22
+ export { default as Slider } from './components/Slider';
23
+ export { default as Snackbar } from './components/Snackbar';
24
+ export { default as Tabs } from './components/Tabs';
25
+ export { default as TextInput } from './components/TextInput';
26
+ export { default as Toolbar } from './components/Toolbar';
27
+ export { default as Window } from './components/Window';
28
+ export { Select, SelectBox } from './components/Select';
29
+ export { Text, Title, Anchor } from './components/Typography';
30
+
31
+ export * from './components/Icons';
32
+ export { default as themes } from './styles/themes';
33
+
34
+ export { Theme } from './types';
35
+ export { fontNames } from './styles/styles';
36
+
37
+ export { useTheme, withTheme, ThemeProvider } from './core/theming';
38
+ export { default as Provider } from './core/Provider';
@@ -0,0 +1,36 @@
1
+ // shadow util copied from https://github.com/callstack/react-native-paper/
2
+
3
+ const SHADOW_COLOR = '#000000';
4
+ const SHADOW_OPACITY = 0.24;
5
+
6
+ export default function shadow(elevation = 0) {
7
+ if (elevation === 0) {
8
+ return {};
9
+ }
10
+
11
+ let height;
12
+ let radius;
13
+ switch (elevation) {
14
+ case 1:
15
+ height = 0.5;
16
+ radius = 0.75;
17
+ break;
18
+ case 2:
19
+ height = 0.75;
20
+ radius = 1.5;
21
+ break;
22
+ default:
23
+ height = elevation - 1;
24
+ radius = elevation;
25
+ }
26
+
27
+ return {
28
+ shadowColor: SHADOW_COLOR,
29
+ shadowOffset: {
30
+ width: 0,
31
+ height,
32
+ },
33
+ shadowOpacity: SHADOW_OPACITY,
34
+ shadowRadius: radius,
35
+ };
36
+ }
@@ -0,0 +1,105 @@
1
+ /* eslint-disable import/prefer-default-export */
2
+ import React from 'react';
3
+ import { StyleSheet, View, StyleProp, ViewStyle } from 'react-native';
4
+
5
+ import { withTheme } from '../core/theming';
6
+
7
+ import { buildBorderStyles } from './styles';
8
+ import type { Theme } from '../types';
9
+
10
+ // Borders acts like a pseudo element that
11
+ // will be positioned absolutely in it's parent element
12
+ type BorderProps = {
13
+ invert?: boolean;
14
+ variant?: 'default' | 'well' | 'raised' | 'cutout' | 'flat';
15
+ style?: StyleProp<ViewStyle>;
16
+ sharedStyle?: StyleProp<ViewStyle>;
17
+ radius?: number;
18
+ children?: React.ReactNode;
19
+ theme: Theme;
20
+ };
21
+
22
+ const Border = ({
23
+ invert = false,
24
+ variant = 'default',
25
+ style = {},
26
+ sharedStyle = {},
27
+ radius = 0,
28
+ theme,
29
+ children,
30
+ }: BorderProps) => {
31
+ const wrapper: StyleProp<ViewStyle> = [];
32
+ let outer;
33
+ let inner;
34
+
35
+ const themedBorders = buildBorderStyles(theme);
36
+
37
+ if (variant === 'default') {
38
+ outer = [themedBorders.defaultOuter];
39
+ inner = [themedBorders.defaultInner];
40
+ } else if (variant === 'raised') {
41
+ outer = [themedBorders.outsideOuter];
42
+ inner = [themedBorders.outsideInner];
43
+ } else if (variant === 'well') {
44
+ outer = [themedBorders.well, borderStyles.invert];
45
+ } else if (variant === 'cutout') {
46
+ outer = [themedBorders.cutoutOuter];
47
+ inner = [themedBorders.cutoutInner];
48
+ } else if (variant === 'flat') {
49
+ outer = [themedBorders.flat];
50
+ }
51
+
52
+ const getSharedStyles = (() => {
53
+ let r = radius + 4;
54
+
55
+ return () => {
56
+ r -= 2;
57
+ return [
58
+ borderStyles.position,
59
+ sharedStyle,
60
+ {
61
+ borderRadius: radius ? r : 0,
62
+ },
63
+ ];
64
+ };
65
+ })();
66
+
67
+ return (
68
+ <View
69
+ style={[
70
+ getSharedStyles(),
71
+ invert ? borderStyles.invert : {},
72
+ ...wrapper,
73
+ style,
74
+ ]}
75
+ >
76
+ {outer ? (
77
+ <View style={[getSharedStyles(), ...outer]}>
78
+ {inner ? (
79
+ <View style={[getSharedStyles(), ...inner]}>{children}</View>
80
+ ) : (
81
+ children
82
+ )}
83
+ </View>
84
+ ) : (
85
+ children
86
+ )}
87
+ </View>
88
+ );
89
+ };
90
+
91
+ const borderStyles = StyleSheet.create({
92
+ position: {
93
+ position: 'absolute',
94
+ top: 0,
95
+ bottom: 0,
96
+ left: 0,
97
+ right: 0,
98
+ },
99
+ invert: {
100
+ transform: [{ rotate: '180deg' }],
101
+ },
102
+ });
103
+
104
+ const BorderWithTheme = withTheme(Border);
105
+ export { BorderWithTheme as Border };
@@ -0,0 +1,129 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ import type { Theme } from '../types';
4
+
5
+ export const fontNames = {
6
+ normal: 'MS Sans Serif',
7
+ bold: 'MS Sans Serif Bold',
8
+ };
9
+
10
+ const commonBorderStyle = { borderWidth: 2 };
11
+
12
+ export const buildBorderStyles = (theme: Theme) =>
13
+ StyleSheet.create({
14
+ focusSecondaryOutline: {
15
+ ...commonBorderStyle,
16
+ borderStyle: 'dotted',
17
+ borderColor: theme.focusSecondary,
18
+ },
19
+ focusOutline: {
20
+ ...commonBorderStyle,
21
+ borderStyle: 'dotted',
22
+ borderColor: theme.borderDarkest,
23
+ },
24
+ outline: {
25
+ ...commonBorderStyle,
26
+ borderColor: theme.borderDarkest,
27
+ },
28
+ defaultOuter: {
29
+ ...commonBorderStyle,
30
+ borderLeftColor: theme.borderLightest,
31
+ borderTopColor: theme.borderLightest,
32
+ borderRightColor: theme.borderDarkest,
33
+ borderBottomColor: theme.borderDarkest,
34
+ },
35
+ defaultInner: {
36
+ ...commonBorderStyle,
37
+ borderLeftColor: theme.borderLight,
38
+ borderTopColor: theme.borderLight,
39
+ borderRightColor: theme.borderDark,
40
+ borderBottomColor: theme.borderDark,
41
+ },
42
+ outsideOuter: {
43
+ ...commonBorderStyle,
44
+ borderLeftColor: theme.borderLight,
45
+ borderTopColor: theme.borderLight,
46
+ borderRightColor: theme.borderDarkest,
47
+ borderBottomColor: theme.borderDarkest,
48
+ },
49
+ outsideInner: {
50
+ ...commonBorderStyle,
51
+ borderLeftColor: theme.borderLightest,
52
+ borderTopColor: theme.borderLightest,
53
+ borderRightColor: theme.borderDark,
54
+ borderBottomColor: theme.borderDark,
55
+ },
56
+ cutoutOuter: {
57
+ ...commonBorderStyle,
58
+ borderLeftColor: theme.borderDark,
59
+ borderTopColor: theme.borderDark,
60
+ borderRightColor: theme.borderLightest,
61
+ borderBottomColor: theme.borderLightest,
62
+ },
63
+ cutoutInner: {
64
+ ...commonBorderStyle,
65
+ borderLeftColor: theme.borderDarkest,
66
+ borderTopColor: theme.borderDarkest,
67
+ borderRightColor: theme.borderLight,
68
+ borderBottomColor: theme.borderLight,
69
+ },
70
+ well: {
71
+ ...commonBorderStyle,
72
+ borderLeftColor: theme.borderLightest,
73
+ borderTopColor: theme.borderLightest,
74
+ borderRightColor: theme.borderDark,
75
+ borderBottomColor: theme.borderDark,
76
+ },
77
+ flat: {
78
+ ...commonBorderStyle,
79
+ borderColor: theme.flatDark,
80
+ },
81
+ });
82
+
83
+ export const builtTextStyles = (theme: Theme) =>
84
+ StyleSheet.create({
85
+ regular: {
86
+ fontFamily: 'MS Sans Serif',
87
+ fontSize: 16,
88
+ },
89
+ bold: {
90
+ fontFamily: 'MS Sans Serif Bold',
91
+ fontSize: 16,
92
+ },
93
+ secondary: {
94
+ color: theme.materialTextDisabled,
95
+ },
96
+ default: {
97
+ color: theme.materialText,
98
+ },
99
+ disabled: {
100
+ color: theme.materialTextDisabled,
101
+ textShadowColor: theme.materialTextDisabledShadow,
102
+ textShadowOffset: { width: 1, height: 1 },
103
+ textShadowRadius: 0,
104
+ },
105
+ });
106
+
107
+ export const blockSizes = {
108
+ sm: 28,
109
+ md: 36,
110
+ lg: 44,
111
+ };
112
+
113
+ export function padding(a: number, b?: number, c?: number, d?: number) {
114
+ return {
115
+ paddingTop: a,
116
+ paddingRight: b || a,
117
+ paddingBottom: c || a,
118
+ paddingLeft: d || b || a,
119
+ };
120
+ }
121
+
122
+ export function margin(a: number, b?: number, c?: number, d?: number) {
123
+ return {
124
+ marginTop: a,
125
+ marginRight: b || a,
126
+ marginBottom: c || a,
127
+ marginLeft: d || b || a,
128
+ };
129
+ }