Skip to content

Commit 9de15c5

Browse files
committed
Initial Commit
0 parents  commit 9de15c5

File tree

12 files changed

+8256
-0
lines changed

12 files changed

+8256
-0
lines changed

.editorconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# EditorConfig is awesome: https://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
[*]
7+
indent_style = space
8+
indent_size = 2
9+
end_of_line = lf
10+
charset = utf-8
11+
trim_trailing_whitespace = true
12+
insert_final_newline = true

.eslintrc.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"env": {
3+
"es2021": true
4+
},
5+
"extends": ["plugin:react/recommended", "standard"],
6+
"parser": "@typescript-eslint/parser",
7+
"parserOptions": {
8+
"ecmaFeatures": {
9+
"jsx": true
10+
},
11+
"ecmaVersion": 12,
12+
"sourceType": "module"
13+
},
14+
"plugins": ["react", "@typescript-eslint"],
15+
"rules": {
16+
"no-use-before-define": "off",
17+
"no-undef": "off",
18+
"@typescript-eslint/no-use-before-define": ["error"],
19+
"react/prop-types": "off",
20+
"react/display-name": "off"
21+
}
22+
}

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules
2+
npm-debug.*
3+
index.js
4+
index.d.ts
5+
.vscode
6+
web-build/
7+
web-report/
8+
coverage
9+
.DS_Store
10+
yarn-error.log

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2021 Andre Pedroza
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
![](https://github.com/andreppedroza/react-native-themed-stylesheet/workflows/Node%20CI/badge.svg)
2+
3+
# react-native-themed-stylesheet
4+
5+
A package that allows you to create React Native StyleSheets with support for Dark/Light/Auto Themes.
6+
7+
- Depends on react-native-appearance to choose the theme based on OS preference (Android 10/iOS 13)
8+
- Simple API
9+
- Fully typed
10+
- Builds on top of StyleSheets and Hooks
11+
12+
## Installation
13+
14+
**Using Expo**
15+
16+
```
17+
expo install react-native-appearance react-native-themed-stylesheet
18+
```
19+
20+
**Using Yarn**
21+
22+
```
23+
yarn add react-native-appearance react-native-themed-stylesheet
24+
```
25+
26+
**Using NPM**
27+
28+
```
29+
npm install --save react-native-appearance react-native-themed-stylesheet
30+
```
31+
32+
## Usage
33+
34+
Defining Themes:
35+
36+
```ts
37+
// themes.ts
38+
39+
import { createTheme } from 'react-native-themed-stylesheet'
40+
41+
const themes = {
42+
light: {
43+
textColor: '#ff0000'
44+
},
45+
dark: {
46+
textColor: '#fff'
47+
},
48+
common: {
49+
//Optional
50+
fontSize: 12
51+
}
52+
}
53+
54+
const { ThemeProvider, useStyle, useTheme } = createTheme(themes, 'auto') //Initial Mode is optional(Default: 'auto')
55+
56+
export { ThemeProvider, useStyle, useTheme }
57+
```
58+
59+
Using themes:
60+
61+
```tsx
62+
// Components.tsx
63+
import React from 'react'
64+
import { View, Text, Button } from 'react-native'
65+
import { ThemeProvider, useStyle, useTheme } from './themes'
66+
import { styleSheetFactory } from './themes'
67+
68+
const ComponentWithUseStyle = () => {
69+
const styles = useStyle(theme => {
70+
text: {
71+
color: theme.textColor,
72+
fontSize: theme.fontSize
73+
}
74+
})
75+
76+
return (
77+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
78+
<Text style={styles.text}>Hello World</Text>
79+
</View>
80+
)
81+
}
82+
83+
const ComponentWithUseTheme = () => {
84+
const { theme, mode, setThemes, setMode } = useTheme()
85+
console.log('Current Mode:', mode)
86+
87+
return (
88+
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
89+
<Text style={{ color: theme.textColor, fontSize: theme.fontSize }}>Hello World</Text>
90+
<Button title='Dark Mode' onPress={() => setMode('dark')}/>
91+
<Button title='Light Mode' onPress={() => setMode('light')}/>
92+
<Button title='Auto Mode' onPress={() => setMode('auto')}/>
93+
<Button title='Change Themes' onPress={
94+
() => setThemes({
95+
light: {
96+
textColor: '#ffff00'
97+
},
98+
dark: {
99+
textColor: '#C9C9C9'
100+
},
101+
common: {
102+
fontSize: 14
103+
}
104+
})
105+
}
106+
/>
107+
</View>
108+
)
109+
}
110+
```
111+
112+
## API
113+
114+
### Function: `createTheme(themes, initialMode)`
115+
116+
Use this function to create the theme.
117+
118+
**Parameters**
119+
120+
- `themes`: An object containing light, dark and an optional common theme(Will be merge with boths themes).
121+
- `initialMode`: A string('light', 'dark' or 'auto') specifying the initial mode(Default: 'auto').
122+
123+
**Returns**
124+
125+
```
126+
127+
ThemeObject
128+
129+
```
130+
131+
---
132+
133+
### Object: `ThemeObject`
134+
135+
An object containing the following properties:
136+
137+
- ThemeProvider: Theme Provider
138+
- useStyle: Hook to create Named StyleSheets
139+
- useTheme: Hook to get access to ThemeContext
140+
141+
---
142+
143+
### React Component: `ThemeProvider`
144+
145+
A react component to provide ThemeContext.
146+
147+
---
148+
149+
### Function: `useStyle(createStyle)`
150+
151+
Use this function to create themed stylesheets.
152+
153+
**Parameters**
154+
155+
- `createStyle`: A function that receive the current theme and return an object of type `T`.
156+
157+
**Returns**
158+
159+
```
160+
161+
StyleSheet.NamedStyles<T>
162+
163+
```
164+
165+
---
166+
167+
### Function: `useTheme()`
168+
169+
Use this function to get theme context.
170+
171+
**Returns**
172+
173+
```
174+
175+
{ theme, mode, setThemes, setMode }
176+
177+
```
178+
179+
An object containing the following properties:
180+
181+
- `theme`: The current theme
182+
- `mode`: The current mode.
183+
- `setThemes`: Function to set the themes(The same type of createTheme themes param).
184+
- `setMode`: Function to set the mode('light', 'dark' or 'auto').
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import * as React from 'react'
2+
import { View } from 'react-native'
3+
import {
4+
AppearancePreferences,
5+
ColorSchemeName,
6+
AppearanceListener
7+
} from 'react-native-appearance/src/Appearance.types'
8+
9+
type EventSubscription = {
10+
remove: () => void
11+
}
12+
13+
export class Appearance {
14+
private static _preference: ColorSchemeName = 'no-preference'
15+
private static _listeners: AppearanceListener[] = []
16+
static getColorScheme (): ColorSchemeName {
17+
return this._preference
18+
}
19+
20+
static get preference (): ColorSchemeName {
21+
return this._preference
22+
}
23+
24+
static set preference (newPreference: ColorSchemeName) {
25+
this._preference = newPreference
26+
this._listeners.forEach(l => l({ colorScheme: this._preference }))
27+
}
28+
29+
static set (_preferences: AppearancePreferences): void {}
30+
31+
static addChangeListener (_listener: AppearanceListener): EventSubscription {
32+
this._listeners.push(_listener)
33+
return {
34+
remove: () => {
35+
this._listeners = this._listeners.filter(l => l !== _listener)
36+
}
37+
}
38+
}
39+
40+
/**
41+
* Unused: some people might expect to remove the listener like this, but they shouldn't.
42+
*/
43+
static removeChangeListener (_listener: AppearanceListener): void {}
44+
}
45+
46+
export const AppearanceProvider = (props: any) => (
47+
<View style={{ flex: 1 }} {...props} />
48+
)
49+
50+
export function useColorScheme (): ColorSchemeName {
51+
return 'no-preference'
52+
}

0 commit comments

Comments
 (0)