This commit is contained in:
2019-08-23 00:12:49 +02:00
committed by GitHub
parent c30e9f27a5
commit fd3a2bc24f
94 changed files with 13855 additions and 9269 deletions

View File

@@ -0,0 +1,29 @@
import React from 'react';
import styled from 'styled-components/native';
import {
Body,
Emphasis,
} from './text';
const Wrapper = styled.View`
flex-direction: row;
padding: 10px;
`;
const Left = styled.View`
width: 100px;
`;
const Row = ({
left,
right,
}) => (
<Wrapper>
<Left>
<Emphasis>{left}:</Emphasis>
</Left>
<Body selectable={true}>{right}</Body>
</Wrapper>
)
export default Row;

View File

@@ -0,0 +1,20 @@
import React from 'react';
import styled from 'styled-components/native';
import {
Emphasis,
} from './text';
const Wrapper = styled.View`
flex-direction: row;
padding: 10px;
`;
const Row = ({
children,
}) => (
<Wrapper>
<Emphasis>{children}:</Emphasis>
</Wrapper>
)
export default Row;

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,47 @@
import React from 'react';
import styled from 'styled-components/native';
import reload from './reload.png';
import trash from './trash.png';
import remove from './return.png';
import right from './right.png';
import left from './left.png';
import play from './play.png';
import download from './download.png';
import close from './close.png';
import filter from './filter.png';
import square from './square.png';
import check from './check.png';
const icons = {
reload,
trash,
remove,
right,
left,
play,
download,
close,
filter,
square,
check,
}
const Image = styled.Image`
height: ${({ height }) => height || '16'}px;
width: ${({ width }) => width || '16'}px;
`;
const Icon = ({
name,
width,
height
}) => (
<Image
width={width}
height={height}
source={icons[name]}
/>
);
export default Icon;

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@@ -0,0 +1,5 @@
import {
Modal
} from 'react-native';
export default Modal;

View File

@@ -0,0 +1,41 @@
import React, { useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import styled from 'styled-components';
const Wrapper = styled.div`
position: fixed;
background: #fff;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
`;
const Modal = ({
visible,
children
}) => {
const [root, setRoot] = useState();
useEffect(() => {
const elm = document.createElement('div');
document.body.appendChild(elm);
setRoot(elm);
}, []);
const elm = visible ? (
<Wrapper>{children}</Wrapper>
) : null;
if (!root) {
return null;
}
return createPortal(
elm,
root,
);
};
export default Modal;

View File

@@ -0,0 +1,37 @@
import React from 'react';
import styled from 'styled-components/native';
const Wrapper = styled.View`
flex-direction: row;
padding: 10px;
border-left-width: ${props => props.selected ? '10px' : '0'};
border-left-color: #2980b9;
border-bottom-width: 1px;
border-bottom-color: #efefef;
`;
const Left = styled.View`
`;
const Right = styled.View`
`;
const Center = styled.View`
flex: 1;
margin: 0 10px;
`;
const Row = ({
left,
right,
children,
selected,
}) => (
<Wrapper selected={selected}>
{left && <Left>{left}</Left>}
<Center>{children}</Center>
{right && <Right>{right}</Right>}
</Wrapper>
)
export default Row;

View File

@@ -0,0 +1,44 @@
import React from 'react';
import styled from 'styled-components/native';
import {
Body,
} from '../base/text';
const getColor = (code) => {
if (code === 'Error') {
return '#c0392b';
}
if (code >= 500) {
return '#c0392b';
}
if (code >= 400) {
return '#f1c40f';
}
if (code >= 300) {
return '#2980b9';
}
return '#2ecc71';
}
const Wrapper = styled.View`
flex-direction: row;
`;
const Icon = styled.View`
width: 16px;
height: 16px;
border-radius: 8px;
background: ${props => getColor(props.code)};
margin-left: 5px;
`;
const Status = ({
code,
}) => (
<Wrapper>
<Body>{code}</Body>
{code !== 'Waiting' && <Icon code={code} />}
</Wrapper>
)
export default Status;

View File

@@ -0,0 +1,31 @@
import React from 'react';
import styled from 'styled-components/native';
import Icon from '../Icon';
import {
Body,
} from '../text';
const Item = styled.TouchableOpacity`
padding: 10px 10px;
opacity: ${({ disabled }) => disabled ? 0.3 : 1};
`;
const Button = ({
name,
icon,
onPress,
disabled,
}) => (
<Item
onPress={disabled ? undefined : onPress}
disabled={disabled}
>
{icon ? (
<Icon name={icon} />
) : (
<Body color={disabled ? '#ccc' : undefined}>{name}</Body>
)}
</Item>
);
export default Button;

View File

@@ -0,0 +1,74 @@
import React, { Fragment, useState } from 'react';
import {
SafeAreaView,
TouchableOpacity,
} from 'react-native';
import Button from './Button';
import Row from '../Row';
import Icon from '../Icon';
import Modal from '../Modal';
import {
Body,
} from '../text';
const Selector = ({
multiSelect = false,
onSelect,
options = [],
...others
}) => {
const [open, setOpen] = useState(false);
return (
<Fragment>
<Button
{...others}
onPress={() => {
setOpen(true);
}}
/>
<Modal
animationType="slide"
transparent={false}
visible={!!open}
onRequestClose={() => {
setOpen(false);
}}
>
<SafeAreaView
forceInset={{ top: 'always', vertical: 'always' }}
style={{flex: 1}}
>
<Button
name="Close"
icon="close"
onPress={() => {
setOpen(false);
}}
/>
{options.map((option) => (
<TouchableOpacity
key={option.name}
onPress={() => {
if (!multiSelect) {
options.forEach(o => o.selected = false);
}
option.selected = !option.selected
onSelect(options);
}}
>
<Row
left={(
<Icon name={option.selected ? 'check' : 'square'} />
)}
>
<Body>{option.name}</Body>
</Row>
</TouchableOpacity>
))}
</SafeAreaView>
</Modal>
</Fragment>
);
};
export default Selector;

View File

@@ -0,0 +1,7 @@
import styled from 'styled-components/native';
const Seperator = styled.View`
flex: 1;
`;
export default Seperator;

View File

@@ -0,0 +1,29 @@
import React from 'react';
import styled from 'styled-components/native';
import Button from './Button';
import Seperator from './Seperator';
import Selector from './Selector';
export {
Button,
Seperator,
Selector,
}
const Wrapper = styled.View`
flex-direction: row;
align-items: center;
border-bottom-width: 1px;
border-color: #ccc;
padding: 0 10px;
`;
const Toolbar = ({
children,
}) => (
<Wrapper>
{children}
</Wrapper>
)
export default Toolbar;

View File

@@ -0,0 +1,14 @@
import styled from 'styled-components/native';
export const Body = styled.Text`
color: ${props => props.color || 'black'};
`;
export const Emphasis = styled.Text`
font-weight: bold;
color: ${props => props.color || 'black'};
`;
export const Fixed = styled.Text`
font-family: Menlo-Regular;
`;