Skip to content
This repository has been archived by the owner on May 31, 2021. It is now read-only.

Commit

Permalink
Proposal on theming dooboo-ui component (#377)
Browse files Browse the repository at this point in the history
The `light` and the `dark` mode is default today and UI components are mandatory to handle these cases. Added ability to `theme` main components which are currently `Button` and `EditText`. We'll cover this further when this works out well.

Deprecated `@dooboo-ui/theme` and integrated into `dooboo-ui` which is the main package. This decision was made to strongly attach `theme` variables into main components.

* Release 0.0.40
  • Loading branch information
hyochan authored Feb 4, 2021
1 parent 801d9a5 commit 3edd7b3
Show file tree
Hide file tree
Showing 29 changed files with 641 additions and 744 deletions.
21 changes: 21 additions & 0 deletions CHANGELOGS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
## Changelogs

## 0.0.40

[Theme]

- Added missing `media` type in `theme`.

## 0.0.39

[Theme]

- Deprecated [@dooboo-ui/theme](https://www.npmjs.com/package/@dooboo-ui/theme) and included in `dooboo-ui` package itself.
- This decision was made to unify the theme props used internally.

[EditText]

- Use theme props in default styling.

[Button]

- Use theme props in default styling.

## 0.0.38

[EditText]
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,17 @@ We love [react-hooks](https://code.fb.com/open-source/react-hooks) and willing t

We aim to support `react-native` ui components in all platforms and we are currently targeting `iOS`, `android` and `web`. If you read [issue on plan for unifying dooboo-ui](https://github.com/dooboolab/dooboo-ui/issues/194), you can see in more detail how we want to drive this project.

## Thememing

Follow the [README_THEME](./README_THEME.md)

## Compatibility

| package | version |
| ----------------- | ------- |
| react | >=16.13 |
| react-native | >=0.62 |
| styled-components | >=5.1.1 |
| styled-components | >=5 |

## List of independent components in `@dooboo-ui/*`

Expand Down
20 changes: 6 additions & 14 deletions packages/theme/README.md → README_THEME.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,15 @@

> The `theme` module easily provides ability to make `light` and `dark` theme.
[![Npm Version](http://img.shields.io/npm/v/@dooboo-ui/theme.svg?style=flat-square)](https://npmjs.org/package/@dooboo-ui/theme)
[![Downloads](http://img.shields.io/npm/dm/@dooboo-ui/theme.svg?style=flat-square)](https://npmjs.org/package/@dooboo-ui/theme)

![theme](https://user-images.githubusercontent.com/27461460/69912924-08864300-1474-11ea-90aa-e815063fe7e6.gif)

## Installation

1. Install via yarn or npm.
`npm install @dooboo-ui/theme` or `yarn add @dooboo-ui/theme`.

2. Import
1. Import

```ts
import {ThemeProvider} from '@dooboo-ui/theme';
import {ThemeProvider} from 'dooboo-ui';
```

3. Create `light` and `dark` theme
2. Create `light` and `dark` theme

```ts
export const colors = {
Expand Down Expand Up @@ -119,7 +111,7 @@
};
```

4. Wrap your component with `ThemeProvider` with given customTheme.
3. Wrap your component with `ThemeProvider` with given customTheme.
```tsx
<ThemeProvider customTheme={{light, dark}}>
<App />
Expand All @@ -131,7 +123,7 @@
1. Import `useThemeContext`

```ts
import {useThemeContext} from '@dooboo-ui/theme';
import {useThemeContext} from 'dooboo-ui';
```

2. Retrive theme.
Expand All @@ -153,7 +145,7 @@
```ts
const StyledContainer = styled.SafeAreaView`
flex: 1;
background-color: ${({theme}): string => theme.background};
background-color: ${({theme}) => theme.background};
flex-direction: column;
align-items: center;
`;
Expand Down
2 changes: 1 addition & 1 deletion environment.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare module '*.svg' {
import { IconType } from './src/types';
import {IconType} from './src/types';

const content: IconType;
export default content;
Expand Down
7 changes: 6 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ module.exports = {
// '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|
// webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/test/assetsTransformer.js'
// },
coveragePathIgnorePatterns: ['.example.', '__assets__', '__tests__'],
coveragePathIgnorePatterns: [
'.example.',
'__assets__',
'__tests__',
'./main/theme',
],
};
5 changes: 3 additions & 2 deletions lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dooboo-ui",
"version": "0.0.38",
"version": "0.0.40",
"main": "index.js",
"types": "index.d.ts",
"author": "dooboolab",
Expand All @@ -16,7 +16,8 @@
},
"dependencies": {
"dooboolab-welcome": "^1.2.0",
"react-native-web-hooks": "^3.0.1"
"react-native-web-hooks": "^3.0.1",
"react-responsive": "^8.2.0"
},
"publishConfig": {
"access": "public"
Expand Down
131 changes: 72 additions & 59 deletions main/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,53 @@ import {
ActivityIndicator,
LayoutRectangle,
Platform,
TouchableOpacity,
} from 'react-native';
import React, {useRef, useState} from 'react';
import type {
StyleProp,
StyleSheet,
Text,
TextProps,
TouchableOpacity,
TextStyle,
TouchableOpacityProps,
View,
ViewStyle,
} from 'react-native';
import React, {useRef, useState} from 'react';
import {Theme, light} from './theme';

import type {FC} from 'react';
import styled from 'styled-components/native';
import {useHover} from 'react-native-web-hooks';
import {withTheme} from './theme/ThemeProvider';

const defaultStyles = StyleSheet.create({
container: {
alignSelf: 'stretch',
paddingHorizontal: 12,
paddingVertical: 8,
borderRadius: 6,
type Styles = {
container?: StyleProp<ViewStyle>;
text?: StyleProp<TextStyle>;
disabledButton?: StyleProp<ViewStyle>;
disabledText?: StyleProp<TextStyle>;
hovered?: StyleProp<ViewStyle>;
};

flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 14,
color: '#069ccd',
},
disabledButton: {
backgroundColor: '#cccccc',
borderColor: 'rgb(200, 200, 200)',
},
disabledText: {
color: '#969696',
},
hovered: {
shadowColor: 'black',
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.24,
shadowRadius: 16,
elevation: 10,
},
});
const Container = styled.View`
align-self: stretch;
padding: 8px 12px;
background-color: ${({theme}) => theme.primary || light.primary};
flex-direction: row;
align-items: center;
justify-content: center;
`;

type StylesType = Partial<StyleSheet.NamedStyles<typeof defaultStyles>>;
const Text = styled.Text`
font-size: 14px;
color: white;
`;

export interface ButtonProps {
testID?: string;
indicatorColor?: string;
loading?: boolean;
disabled?: boolean;
style?: StyleProp<ViewStyle>;
styles?: StylesType;
styles?: Styles;
leftElement?: React.ReactElement;
rightElement?: React.ReactElement;
activeOpacity?: TouchableOpacityProps['activeOpacity'];
Expand All @@ -67,25 +58,48 @@ export interface ButtonProps {
textProps?: Partial<TextProps>;
}

function Button({
const Component: FC<ButtonProps & {theme: Theme}> = ({
testID,
theme,
disabled,
loading,
style,
styles,
indicatorColor = '#ffffff',
indicatorColor = theme.contrastText,
leftElement,
rightElement,
activeOpacity = 0.7,
text,
onPress,
touchableOpacityProps,
textProps,
}: ButtonProps): React.ReactElement {
}) => {
const ref = useRef<TouchableOpacity>(null);
const hovered = useHover(ref);
const [layout, setLayout] = useState<LayoutRectangle>();

const compositeStyles: Styles = {
disabledButton: {
backgroundColor: theme.disabled,
borderColor: theme.primary,
},
disabledText: {
color: theme.disabledText,
},
hovered: {
borderColor: theme.primary,
shadowColor: 'black',
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.24,
shadowRadius: 16,
elevation: 10,
},
...styles,
};

return (
<TouchableOpacity
testID={testID}
Expand All @@ -100,45 +114,44 @@ function Button({
style={style}
{...touchableOpacityProps}>
{loading ? (
<View
<Container
testID="loading-view"
style={[
defaultStyles.container,
styles?.container,
compositeStyles.container,
{
width: layout?.width,
height: layout?.height,
},
hovered && !disabled && [defaultStyles.hovered, styles?.hovered],
disabled && [defaultStyles.disabledButton, styles?.disabledButton],
hovered && !disabled && compositeStyles.hovered,
disabled && compositeStyles.disabledButton,
]}>
<ActivityIndicator size="small" color={indicatorColor} />
</View>
</Container>
) : (
<View
<Container
testID="button-view"
style={[
defaultStyles.container,
styles?.container,
hovered && !disabled && [defaultStyles.hovered, styles?.hovered],
disabled && [defaultStyles.disabledButton, styles?.disabledButton],
compositeStyles.container,
hovered && !disabled && compositeStyles.hovered,
disabled && compositeStyles.disabledButton,
]}
onLayout={(e) => setLayout(e.nativeEvent.layout)}>
{leftElement}
<Text
style={[
defaultStyles.text,
styles?.text,
disabled && [defaultStyles.disabledText, styles?.disabledText],
compositeStyles.text,
disabled && compositeStyles.disabledText,
]}
{...textProps}>
{text}
</Text>
{rightElement}
</View>
</Container>
)}
</TouchableOpacity>
);
}
};

Component.defaultProps = {theme: light};

export {Button};
export const Button = withTheme(Component);
Loading

0 comments on commit 3edd7b3

Please sign in to comment.