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.
- package/LICENSE +21 -0
- package/README.md +24 -0
- package/package.json +154 -0
- package/src/assets/fonts/src/ms-sans-serif/MS Sans Serif.ttf +0 -0
- package/src/assets/fonts/src/ms-sans-serif/license.txt +4 -0
- package/src/assets/fonts/src/ms-sans-serif/readme.txt +26 -0
- package/src/assets/fonts/src/ms-sans-serif-bold/MS Sans Serif Bold.ttf +0 -0
- package/src/assets/fonts/src/ms-sans-serif-bold/license.txt +4 -0
- package/src/assets/fonts/src/ms-sans-serif-bold/readme.txt +26 -0
- package/src/components/AppBar/AppBar.spec.tsx +140 -0
- package/src/components/AppBar/AppBar.tsx +43 -0
- package/src/components/AppBar/AppBarBackAction.tsx +20 -0
- package/src/components/AppBar/AppBarContent.tsx +84 -0
- package/src/components/AppBar/index.ts +1 -0
- package/src/components/Button/Button.spec.tsx +59 -0
- package/src/components/Button/Button.tsx +236 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Card/Card.spec.tsx +54 -0
- package/src/components/Card/Card.tsx +88 -0
- package/src/components/Card/CardContent.tsx +23 -0
- package/src/components/Card/index.ts +1 -0
- package/src/components/Checkbox/Checkbox.tsx +10 -0
- package/src/components/Checkbox/index.ts +1 -0
- package/src/components/ColorButton/ColorButton.tsx +69 -0
- package/src/components/ColorButton/index.ts +1 -0
- package/src/components/ColorPicker/ColorPicker.tsx +109 -0
- package/src/components/ColorPicker/index.ts +1 -0
- package/src/components/Desktop/Desktop.spec.tsx +32 -0
- package/src/components/Desktop/Desktop.tsx +132 -0
- package/src/components/Desktop/index.tsx +1 -0
- package/src/components/Divider/Divider.spec.tsx +47 -0
- package/src/components/Divider/Divider.tsx +52 -0
- package/src/components/Divider/index.tsx +1 -0
- package/src/components/FAB/FAB.tsx +288 -0
- package/src/components/FAB/FABGroup.tsx +385 -0
- package/src/components/FAB/index.ts +1 -0
- package/src/components/Fieldset/Fieldset.spec.tsx +48 -0
- package/src/components/Fieldset/Fieldset.tsx +107 -0
- package/src/components/Fieldset/index.ts +1 -0
- package/src/components/Hourglass/Hourglass.spec.tsx +24 -0
- package/src/components/Hourglass/Hourglass.tsx +43 -0
- package/src/components/Hourglass/base64hourglass.ts +3 -0
- package/src/components/Hourglass/index.ts +1 -0
- package/src/components/Icons/ArrowIcon.tsx +85 -0
- package/src/components/Icons/CheckmarkIcon.tsx +55 -0
- package/src/components/Icons/ChevronIcon.tsx +93 -0
- package/src/components/Icons/CloseIcon.tsx +48 -0
- package/src/components/Icons/index.ts +4 -0
- package/src/components/Label/Label.tsx +77 -0
- package/src/components/Label/index.ts +1 -0
- package/src/components/List/List.tsx +3 -0
- package/src/components/List/ListAccordion.tsx +154 -0
- package/src/components/List/ListItem.tsx +74 -0
- package/src/components/List/ListSection.tsx +51 -0
- package/src/components/List/index.ts +3 -0
- package/src/components/Menu/Menu.tsx +100 -0
- package/src/components/Menu/MenuItem.tsx +100 -0
- package/src/components/Menu/index.ts +1 -0
- package/src/components/NumberInput/NumberInput.spec.tsx +119 -0
- package/src/components/NumberInput/NumberInput.tsx +144 -0
- package/src/components/NumberInput/index.ts +1 -0
- package/src/components/Panel/Panel.spec.tsx +29 -0
- package/src/components/Panel/Panel.tsx +75 -0
- package/src/components/Panel/index.ts +1 -0
- package/src/components/Portal/Portal.tsx +52 -0
- package/src/components/Portal/PortalConsumer.tsx +48 -0
- package/src/components/Portal/PortalHost.tsx +150 -0
- package/src/components/Portal/PortalManager.tsx +57 -0
- package/src/components/Portal/index.ts +1 -0
- package/src/components/Progress/Progress.tsx +125 -0
- package/src/components/Progress/index.ts +1 -0
- package/src/components/Radio/Radio.tsx +14 -0
- package/src/components/Radio/index.ts +1 -0
- package/src/components/ScrollPanel/ScrollPanel.tsx +72 -0
- package/src/components/ScrollPanel/index.ts +1 -0
- package/src/components/ScrollView/ScrollView.tsx +284 -0
- package/src/components/ScrollView/index.ts +1 -0
- package/src/components/Select/Select.tsx +229 -0
- package/src/components/Select/SelectBase.tsx +119 -0
- package/src/components/Select/SelectBox.tsx +66 -0
- package/src/components/Select/index.ts +2 -0
- package/src/components/Slider/Slider.tsx +301 -0
- package/src/components/Slider/index.ts +1 -0
- package/src/components/Snackbar/Snackbar.tsx +260 -0
- package/src/components/Snackbar/SnackbarContent.tsx +23 -0
- package/src/components/Snackbar/index.ts +1 -0
- package/src/components/SwitchBase/SwitchBase.tsx +193 -0
- package/src/components/SwitchBase/index.ts +1 -0
- package/src/components/Tabs/Tabs.tsx +208 -0
- package/src/components/Tabs/index.ts +1 -0
- package/src/components/TextInput/TextInput.tsx +82 -0
- package/src/components/TextInput/index.ts +1 -0
- package/src/components/Toolbar/Toolbar.tsx +113 -0
- package/src/components/Toolbar/index.ts +1 -0
- package/src/components/Typography/Anchor.tsx +38 -0
- package/src/components/Typography/Text.spec.tsx +30 -0
- package/src/components/Typography/Text.tsx +55 -0
- package/src/components/Typography/Title.tsx +58 -0
- package/src/components/Typography/index.ts +3 -0
- package/src/components/Window/Window.tsx +132 -0
- package/src/components/Window/index.ts +1 -0
- package/src/core/Provider.tsx +52 -0
- package/src/core/theming.tsx +8 -0
- package/src/hooks/useAsyncReference.ts +22 -0
- package/src/hooks/useControlledOrUncontrolled.ts +23 -0
- package/src/index.ts +38 -0
- package/src/styles/shadow.tsx +36 -0
- package/src/styles/styleElements.tsx +105 -0
- package/src/styles/styles.ts +129 -0
- package/src/styles/themes/aiee.ts +36 -0
- package/src/styles/themes/ash.ts +35 -0
- package/src/styles/themes/azureOrange.ts +33 -0
- package/src/styles/themes/bee.ts +33 -0
- package/src/styles/themes/blackAndWhite.ts +33 -0
- package/src/styles/themes/blue.ts +36 -0
- package/src/styles/themes/brick.ts +33 -0
- package/src/styles/themes/candy.ts +33 -0
- package/src/styles/themes/cherry.ts +36 -0
- package/src/styles/themes/coldGray.ts +34 -0
- package/src/styles/themes/counterStrike.ts +33 -0
- package/src/styles/themes/darkTeal.ts +36 -0
- package/src/styles/themes/eggplant.ts +33 -0
- package/src/styles/themes/fxDev.ts +36 -0
- package/src/styles/themes/highContrast.ts +33 -0
- package/src/styles/themes/hotChocolate.ts +36 -0
- package/src/styles/themes/index.ts +103 -0
- package/src/styles/themes/lilac.ts +33 -0
- package/src/styles/themes/lilacRoseDark.ts +34 -0
- package/src/styles/themes/maple.ts +33 -0
- package/src/styles/themes/marine.ts +33 -0
- package/src/styles/themes/matrix.ts +33 -0
- package/src/styles/themes/millenium.ts +33 -0
- package/src/styles/themes/modernDark.ts +33 -0
- package/src/styles/themes/molecule.ts +33 -0
- package/src/styles/themes/monochrome.ts +0 -0
- package/src/styles/themes/ninjaTurtles.ts +33 -0
- package/src/styles/themes/olive.ts +33 -0
- package/src/styles/themes/original.ts +33 -0
- package/src/styles/themes/pamelaAnderson.ts +33 -0
- package/src/styles/themes/plum.ts +33 -0
- package/src/styles/themes/polarized.ts +36 -0
- package/src/styles/themes/powerShell.ts +36 -0
- package/src/styles/themes/rainyDay.ts +33 -0
- package/src/styles/themes/raspberry.ts +36 -0
- package/src/styles/themes/redWine.ts +36 -0
- package/src/styles/themes/rose.ts +33 -0
- package/src/styles/themes/seawater.ts +36 -0
- package/src/styles/themes/slate.ts +33 -0
- package/src/styles/themes/solarizedDark.ts +36 -0
- package/src/styles/themes/solarizedLight.ts +36 -0
- package/src/styles/themes/spruce.ts +33 -0
- package/src/styles/themes/stormClouds.ts +36 -0
- package/src/styles/themes/theSixtiesUSA.ts +33 -0
- package/src/styles/themes/tokyoDark.ts +33 -0
- package/src/styles/themes/tooSexy.ts +33 -0
- package/src/styles/themes/travel.ts +33 -0
- package/src/styles/themes/vaporTeal.ts +33 -0
- package/src/styles/themes/vermillion.ts +33 -0
- package/src/styles/themes/violetDark.ts +33 -0
- package/src/styles/themes/water.ts +33 -0
- package/src/styles/themes/wmii.ts +36 -0
- package/src/types.tsx +55 -0
- 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,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,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
|
+
}
|