aport-tools 1.0.1 → 1.0.2
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/.babelrc +8 -0
- package/.expo/README.md +15 -0
- package/.expo/devices.json +3 -0
- package/.expo/settings.json +8 -0
- package/App.tsx +41 -0
- package/dist/Button.d.ts +12 -0
- package/dist/Theme/ThemeContext.d.ts +13 -0
- package/dist/Theme/ThemeToggle.d.ts +3 -0
- package/dist/Theme/index.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +257 -0
- package/dist/index.js +261 -0
- package/dist/styles/colors.d.ts +17 -0
- package/dist/styles/theme.d.ts +4 -0
- package/index.ts +1 -0
- package/package.json +27 -8
- package/rollup.config.mjs +55 -0
- package/rollup.config.js +0 -31
- package/src/Button.tsx +0 -104
- package/src/components/ThemeToggle.tsx +0 -39
- package/src/context/ThemeContext.tsx +0 -70
- package/src/index.ts +0 -1
- package/src/styles/colors.ts +0 -60
- package/src/styles/theme.ts +0 -50
- package/tsconfig.json +0 -30
package/.babelrc
ADDED
package/.expo/README.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
> Why do I have a folder named ".expo" in my project?
|
2
|
+
|
3
|
+
The ".expo" folder is created when an Expo project is started using "expo start" command.
|
4
|
+
|
5
|
+
> What do the files contain?
|
6
|
+
|
7
|
+
- "devices.json": contains information about devices that have recently opened this project. This is used to populate the "Development sessions" list in your development builds.
|
8
|
+
- "packager-info.json": contains port numbers and process PIDs that are used to serve the application to the mobile device/simulator.
|
9
|
+
- "settings.json": contains the server configuration that is used to serve the application manifest.
|
10
|
+
|
11
|
+
> Should I commit the ".expo" folder?
|
12
|
+
|
13
|
+
No, you should not share the ".expo" folder. It does not contain any information that is relevant for other developers working on the project, it is specific to your machine.
|
14
|
+
|
15
|
+
Upon project creation, the ".expo" folder is already added to your ".gitignore" file.
|
package/App.tsx
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
// src/App.tsx
|
2
|
+
|
3
|
+
import React from 'react';
|
4
|
+
import { SafeAreaView, StatusBar, Text, StyleSheet, AppRegistry } from 'react-native';
|
5
|
+
import { ThemeProvider, ThemeContext } from './src/Theme/ThemeContext';
|
6
|
+
import ThemeToggle from './src/Theme/ThemeToggle'; // Import ThemeToggle
|
7
|
+
import { name as appName } from './app.json'; // Ensure this path is correct
|
8
|
+
|
9
|
+
const App: React.FC = () => {
|
10
|
+
return (
|
11
|
+
<ThemeProvider>
|
12
|
+
<ThemeContext.Consumer>
|
13
|
+
{({ theme }) => (
|
14
|
+
<SafeAreaView style={[styles.container, { backgroundColor: theme.colors.background.hex }]}>
|
15
|
+
<StatusBar barStyle={theme.colors.text.hex === '#FFFFFF' ? 'light-content' : 'dark-content'} />
|
16
|
+
<Text style={[styles.text, { color: theme.colors.text.hex }]}>
|
17
|
+
Current Theme: {theme.colors.primary.hex === '#1A73E8' ? 'Light' : 'Dark'}
|
18
|
+
</Text>
|
19
|
+
<ThemeToggle />
|
20
|
+
</SafeAreaView>
|
21
|
+
)}
|
22
|
+
</ThemeContext.Consumer>
|
23
|
+
</ThemeProvider>
|
24
|
+
);
|
25
|
+
};
|
26
|
+
|
27
|
+
const styles = StyleSheet.create({
|
28
|
+
container: {
|
29
|
+
flex: 1,
|
30
|
+
alignItems: 'center',
|
31
|
+
justifyContent: 'center',
|
32
|
+
padding: 20,
|
33
|
+
},
|
34
|
+
text: {
|
35
|
+
fontSize: 24,
|
36
|
+
marginBottom: 20,
|
37
|
+
},
|
38
|
+
});
|
39
|
+
|
40
|
+
|
41
|
+
export default App;
|
package/dist/Button.d.ts
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
interface ButtonProps {
|
3
|
+
disabled?: boolean;
|
4
|
+
isFullWidth?: boolean;
|
5
|
+
children?: string;
|
6
|
+
onPress?: () => void;
|
7
|
+
rounded?: boolean;
|
8
|
+
borderRadius?: number;
|
9
|
+
type?: 'submit' | 'button' | 'cancel';
|
10
|
+
}
|
11
|
+
declare const Button: React.FC<ButtonProps>;
|
12
|
+
export default Button;
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import React, { ReactNode } from 'react';
|
2
|
+
import { Theme } from '../styles/theme';
|
3
|
+
interface ThemeContextProps {
|
4
|
+
theme: Theme;
|
5
|
+
toggleTheme: () => void;
|
6
|
+
}
|
7
|
+
export declare const ThemeContext: React.Context<ThemeContextProps>;
|
8
|
+
interface ThemeProviderProps {
|
9
|
+
children: ReactNode;
|
10
|
+
initialTheme?: 'light' | 'dark';
|
11
|
+
}
|
12
|
+
export declare const ThemeProvider: React.FC<ThemeProviderProps>;
|
13
|
+
export {};
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from './Theme';
|
package/dist/index.es.js
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
/*! aport-tools v1.0.2 | ISC */
|
2
|
+
import React, { createContext, useState, useEffect, useContext } from 'react';
|
3
|
+
import { Appearance, StyleSheet, View, Text, Switch } from 'react-native';
|
4
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
5
|
+
|
6
|
+
/******************************************************************************
|
7
|
+
Copyright (c) Microsoft Corporation.
|
8
|
+
|
9
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
10
|
+
purpose with or without fee is hereby granted.
|
11
|
+
|
12
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
13
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
14
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
15
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
16
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
17
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
18
|
+
PERFORMANCE OF THIS SOFTWARE.
|
19
|
+
***************************************************************************** */
|
20
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
21
|
+
|
22
|
+
|
23
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
24
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
25
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
26
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
27
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
28
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
29
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
function __generator(thisArg, body) {
|
34
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
35
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
36
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
37
|
+
function step(op) {
|
38
|
+
if (f) throw new TypeError("Generator is already executing.");
|
39
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
40
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
41
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
42
|
+
switch (op[0]) {
|
43
|
+
case 0: case 1: t = op; break;
|
44
|
+
case 4: _.label++; return { value: op[1], done: false };
|
45
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
46
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
47
|
+
default:
|
48
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
49
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
50
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
51
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
52
|
+
if (t[2]) _.ops.pop();
|
53
|
+
_.trys.pop(); continue;
|
54
|
+
}
|
55
|
+
op = body.call(thisArg, _);
|
56
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
57
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
62
|
+
var e = new Error(message);
|
63
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
64
|
+
};
|
65
|
+
|
66
|
+
// src/styles/colors.ts
|
67
|
+
var lightTheme = {
|
68
|
+
primary: {
|
69
|
+
hex: '#1A73E8',
|
70
|
+
rgb: {
|
71
|
+
r: 26,
|
72
|
+
g: 115,
|
73
|
+
b: 232
|
74
|
+
}
|
75
|
+
},
|
76
|
+
secondary: {
|
77
|
+
hex: '#F0F6FF',
|
78
|
+
rgb: {
|
79
|
+
r: 240,
|
80
|
+
g: 246,
|
81
|
+
b: 255
|
82
|
+
}
|
83
|
+
},
|
84
|
+
background: {
|
85
|
+
hex: '#FFFFFF',
|
86
|
+
rgb: {
|
87
|
+
r: 255,
|
88
|
+
g: 255,
|
89
|
+
b: 255
|
90
|
+
}
|
91
|
+
},
|
92
|
+
text: {
|
93
|
+
hex: '#000000',
|
94
|
+
rgb: {
|
95
|
+
r: 0,
|
96
|
+
g: 0,
|
97
|
+
b: 0
|
98
|
+
}
|
99
|
+
}
|
100
|
+
// Add more categories as needed
|
101
|
+
};
|
102
|
+
var darkTheme = {
|
103
|
+
primary: {
|
104
|
+
hex: '#BB86FC',
|
105
|
+
rgb: {
|
106
|
+
r: 187,
|
107
|
+
g: 134,
|
108
|
+
b: 252
|
109
|
+
}
|
110
|
+
},
|
111
|
+
secondary: {
|
112
|
+
hex: '#03DAC6',
|
113
|
+
rgb: {
|
114
|
+
r: 3,
|
115
|
+
g: 218,
|
116
|
+
b: 198
|
117
|
+
}
|
118
|
+
},
|
119
|
+
background: {
|
120
|
+
hex: '#121212',
|
121
|
+
rgb: {
|
122
|
+
r: 18,
|
123
|
+
g: 18,
|
124
|
+
b: 18
|
125
|
+
}
|
126
|
+
},
|
127
|
+
text: {
|
128
|
+
hex: '#FFFFFF',
|
129
|
+
rgb: {
|
130
|
+
r: 255,
|
131
|
+
g: 255,
|
132
|
+
b: 255
|
133
|
+
}
|
134
|
+
}
|
135
|
+
// Add more categories as needed
|
136
|
+
};
|
137
|
+
|
138
|
+
var ThemeContext = /*#__PURE__*/createContext({
|
139
|
+
theme: {
|
140
|
+
colors: lightTheme
|
141
|
+
},
|
142
|
+
toggleTheme: function toggleTheme() {}
|
143
|
+
});
|
144
|
+
var ThemeProvider = function ThemeProvider(_a) {
|
145
|
+
var children = _a.children,
|
146
|
+
initialTheme = _a.initialTheme;
|
147
|
+
var _b = useState(null),
|
148
|
+
colorScheme = _b[0],
|
149
|
+
setColorScheme = _b[1];
|
150
|
+
useEffect(function () {
|
151
|
+
var loadTheme = function loadTheme() {
|
152
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
153
|
+
var storedTheme, systemTheme, error_1;
|
154
|
+
return __generator(this, function (_a) {
|
155
|
+
switch (_a.label) {
|
156
|
+
case 0:
|
157
|
+
_a.trys.push([0, 2,, 3]);
|
158
|
+
return [4 /*yield*/, AsyncStorage.getItem('theme')];
|
159
|
+
case 1:
|
160
|
+
storedTheme = _a.sent();
|
161
|
+
if (storedTheme === 'dark' || storedTheme === 'light') {
|
162
|
+
setColorScheme(storedTheme);
|
163
|
+
} else if (initialTheme) {
|
164
|
+
setColorScheme(initialTheme); // Use initialTheme if provided
|
165
|
+
} else {
|
166
|
+
systemTheme = Appearance.getColorScheme();
|
167
|
+
setColorScheme(systemTheme);
|
168
|
+
}
|
169
|
+
return [3 /*break*/, 3];
|
170
|
+
case 2:
|
171
|
+
error_1 = _a.sent();
|
172
|
+
console.error('Failed to load theme.', error_1);
|
173
|
+
setColorScheme(Appearance.getColorScheme());
|
174
|
+
return [3 /*break*/, 3];
|
175
|
+
case 3:
|
176
|
+
return [2 /*return*/];
|
177
|
+
}
|
178
|
+
});
|
179
|
+
});
|
180
|
+
};
|
181
|
+
loadTheme();
|
182
|
+
var subscription = Appearance.addChangeListener(function (_a) {
|
183
|
+
var colorScheme = _a.colorScheme;
|
184
|
+
setColorScheme(colorScheme);
|
185
|
+
});
|
186
|
+
return function () {
|
187
|
+
return subscription.remove();
|
188
|
+
};
|
189
|
+
}, [initialTheme]);
|
190
|
+
var toggleTheme = function toggleTheme() {
|
191
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
192
|
+
var newTheme, error_2;
|
193
|
+
return __generator(this, function (_a) {
|
194
|
+
switch (_a.label) {
|
195
|
+
case 0:
|
196
|
+
_a.trys.push([0, 2,, 3]);
|
197
|
+
newTheme = colorScheme === 'dark' ? 'light' : 'dark';
|
198
|
+
setColorScheme(newTheme);
|
199
|
+
return [4 /*yield*/, AsyncStorage.setItem('theme', newTheme)];
|
200
|
+
case 1:
|
201
|
+
_a.sent();
|
202
|
+
return [3 /*break*/, 3];
|
203
|
+
case 2:
|
204
|
+
error_2 = _a.sent();
|
205
|
+
console.error('Failed to toggle theme.', error_2);
|
206
|
+
return [3 /*break*/, 3];
|
207
|
+
case 3:
|
208
|
+
return [2 /*return*/];
|
209
|
+
}
|
210
|
+
});
|
211
|
+
});
|
212
|
+
};
|
213
|
+
var theme = {
|
214
|
+
colors: colorScheme === 'dark' ? darkTheme : lightTheme
|
215
|
+
};
|
216
|
+
return /*#__PURE__*/React.createElement(ThemeContext.Provider, {
|
217
|
+
value: {
|
218
|
+
theme: theme,
|
219
|
+
toggleTheme: toggleTheme
|
220
|
+
}
|
221
|
+
}, children);
|
222
|
+
};
|
223
|
+
|
224
|
+
var ThemeToggle = function ThemeToggle() {
|
225
|
+
var _a = useContext(ThemeContext),
|
226
|
+
theme = _a.theme,
|
227
|
+
toggleTheme = _a.toggleTheme;
|
228
|
+
var isDarkMode = theme.colors === darkTheme;
|
229
|
+
return /*#__PURE__*/React.createElement(View, {
|
230
|
+
style: styles.container
|
231
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
232
|
+
style: [styles.text, {
|
233
|
+
color: theme.colors.text.hex
|
234
|
+
}]
|
235
|
+
}, "Dark Mode"), /*#__PURE__*/React.createElement(Switch, {
|
236
|
+
value: isDarkMode,
|
237
|
+
onValueChange: toggleTheme,
|
238
|
+
trackColor: {
|
239
|
+
"false": lightTheme.secondary.hex,
|
240
|
+
"true": darkTheme.primary.hex
|
241
|
+
},
|
242
|
+
thumbColor: isDarkMode ? darkTheme.secondary.hex : lightTheme.primary.hex
|
243
|
+
}));
|
244
|
+
};
|
245
|
+
var styles = StyleSheet.create({
|
246
|
+
container: {
|
247
|
+
marginTop: 20,
|
248
|
+
flexDirection: 'row',
|
249
|
+
alignItems: 'center'
|
250
|
+
},
|
251
|
+
text: {
|
252
|
+
marginRight: 10,
|
253
|
+
fontSize: 16
|
254
|
+
}
|
255
|
+
});
|
256
|
+
|
257
|
+
export { ThemeContext, ThemeProvider, ThemeToggle };
|
package/dist/index.js
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
/*! aport-tools v1.0.2 | ISC */
|
2
|
+
'use strict';
|
3
|
+
|
4
|
+
var React = require('react');
|
5
|
+
var reactNative = require('react-native');
|
6
|
+
var AsyncStorage = require('@react-native-async-storage/async-storage');
|
7
|
+
|
8
|
+
/******************************************************************************
|
9
|
+
Copyright (c) Microsoft Corporation.
|
10
|
+
|
11
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
12
|
+
purpose with or without fee is hereby granted.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
15
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
16
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
17
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
18
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
19
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
20
|
+
PERFORMANCE OF THIS SOFTWARE.
|
21
|
+
***************************************************************************** */
|
22
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
23
|
+
|
24
|
+
|
25
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
32
|
+
});
|
33
|
+
}
|
34
|
+
|
35
|
+
function __generator(thisArg, body) {
|
36
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
37
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
38
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
39
|
+
function step(op) {
|
40
|
+
if (f) throw new TypeError("Generator is already executing.");
|
41
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
42
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
43
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
44
|
+
switch (op[0]) {
|
45
|
+
case 0: case 1: t = op; break;
|
46
|
+
case 4: _.label++; return { value: op[1], done: false };
|
47
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
48
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
49
|
+
default:
|
50
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
51
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
52
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
53
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
54
|
+
if (t[2]) _.ops.pop();
|
55
|
+
_.trys.pop(); continue;
|
56
|
+
}
|
57
|
+
op = body.call(thisArg, _);
|
58
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
59
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
64
|
+
var e = new Error(message);
|
65
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
66
|
+
};
|
67
|
+
|
68
|
+
// src/styles/colors.ts
|
69
|
+
var lightTheme = {
|
70
|
+
primary: {
|
71
|
+
hex: '#1A73E8',
|
72
|
+
rgb: {
|
73
|
+
r: 26,
|
74
|
+
g: 115,
|
75
|
+
b: 232
|
76
|
+
}
|
77
|
+
},
|
78
|
+
secondary: {
|
79
|
+
hex: '#F0F6FF',
|
80
|
+
rgb: {
|
81
|
+
r: 240,
|
82
|
+
g: 246,
|
83
|
+
b: 255
|
84
|
+
}
|
85
|
+
},
|
86
|
+
background: {
|
87
|
+
hex: '#FFFFFF',
|
88
|
+
rgb: {
|
89
|
+
r: 255,
|
90
|
+
g: 255,
|
91
|
+
b: 255
|
92
|
+
}
|
93
|
+
},
|
94
|
+
text: {
|
95
|
+
hex: '#000000',
|
96
|
+
rgb: {
|
97
|
+
r: 0,
|
98
|
+
g: 0,
|
99
|
+
b: 0
|
100
|
+
}
|
101
|
+
}
|
102
|
+
// Add more categories as needed
|
103
|
+
};
|
104
|
+
var darkTheme = {
|
105
|
+
primary: {
|
106
|
+
hex: '#BB86FC',
|
107
|
+
rgb: {
|
108
|
+
r: 187,
|
109
|
+
g: 134,
|
110
|
+
b: 252
|
111
|
+
}
|
112
|
+
},
|
113
|
+
secondary: {
|
114
|
+
hex: '#03DAC6',
|
115
|
+
rgb: {
|
116
|
+
r: 3,
|
117
|
+
g: 218,
|
118
|
+
b: 198
|
119
|
+
}
|
120
|
+
},
|
121
|
+
background: {
|
122
|
+
hex: '#121212',
|
123
|
+
rgb: {
|
124
|
+
r: 18,
|
125
|
+
g: 18,
|
126
|
+
b: 18
|
127
|
+
}
|
128
|
+
},
|
129
|
+
text: {
|
130
|
+
hex: '#FFFFFF',
|
131
|
+
rgb: {
|
132
|
+
r: 255,
|
133
|
+
g: 255,
|
134
|
+
b: 255
|
135
|
+
}
|
136
|
+
}
|
137
|
+
// Add more categories as needed
|
138
|
+
};
|
139
|
+
|
140
|
+
var ThemeContext = /*#__PURE__*/React.createContext({
|
141
|
+
theme: {
|
142
|
+
colors: lightTheme
|
143
|
+
},
|
144
|
+
toggleTheme: function toggleTheme() {}
|
145
|
+
});
|
146
|
+
var ThemeProvider = function ThemeProvider(_a) {
|
147
|
+
var children = _a.children,
|
148
|
+
initialTheme = _a.initialTheme;
|
149
|
+
var _b = React.useState(null),
|
150
|
+
colorScheme = _b[0],
|
151
|
+
setColorScheme = _b[1];
|
152
|
+
React.useEffect(function () {
|
153
|
+
var loadTheme = function loadTheme() {
|
154
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
155
|
+
var storedTheme, systemTheme, error_1;
|
156
|
+
return __generator(this, function (_a) {
|
157
|
+
switch (_a.label) {
|
158
|
+
case 0:
|
159
|
+
_a.trys.push([0, 2,, 3]);
|
160
|
+
return [4 /*yield*/, AsyncStorage.getItem('theme')];
|
161
|
+
case 1:
|
162
|
+
storedTheme = _a.sent();
|
163
|
+
if (storedTheme === 'dark' || storedTheme === 'light') {
|
164
|
+
setColorScheme(storedTheme);
|
165
|
+
} else if (initialTheme) {
|
166
|
+
setColorScheme(initialTheme); // Use initialTheme if provided
|
167
|
+
} else {
|
168
|
+
systemTheme = reactNative.Appearance.getColorScheme();
|
169
|
+
setColorScheme(systemTheme);
|
170
|
+
}
|
171
|
+
return [3 /*break*/, 3];
|
172
|
+
case 2:
|
173
|
+
error_1 = _a.sent();
|
174
|
+
console.error('Failed to load theme.', error_1);
|
175
|
+
setColorScheme(reactNative.Appearance.getColorScheme());
|
176
|
+
return [3 /*break*/, 3];
|
177
|
+
case 3:
|
178
|
+
return [2 /*return*/];
|
179
|
+
}
|
180
|
+
});
|
181
|
+
});
|
182
|
+
};
|
183
|
+
loadTheme();
|
184
|
+
var subscription = reactNative.Appearance.addChangeListener(function (_a) {
|
185
|
+
var colorScheme = _a.colorScheme;
|
186
|
+
setColorScheme(colorScheme);
|
187
|
+
});
|
188
|
+
return function () {
|
189
|
+
return subscription.remove();
|
190
|
+
};
|
191
|
+
}, [initialTheme]);
|
192
|
+
var toggleTheme = function toggleTheme() {
|
193
|
+
return __awaiter(void 0, void 0, void 0, function () {
|
194
|
+
var newTheme, error_2;
|
195
|
+
return __generator(this, function (_a) {
|
196
|
+
switch (_a.label) {
|
197
|
+
case 0:
|
198
|
+
_a.trys.push([0, 2,, 3]);
|
199
|
+
newTheme = colorScheme === 'dark' ? 'light' : 'dark';
|
200
|
+
setColorScheme(newTheme);
|
201
|
+
return [4 /*yield*/, AsyncStorage.setItem('theme', newTheme)];
|
202
|
+
case 1:
|
203
|
+
_a.sent();
|
204
|
+
return [3 /*break*/, 3];
|
205
|
+
case 2:
|
206
|
+
error_2 = _a.sent();
|
207
|
+
console.error('Failed to toggle theme.', error_2);
|
208
|
+
return [3 /*break*/, 3];
|
209
|
+
case 3:
|
210
|
+
return [2 /*return*/];
|
211
|
+
}
|
212
|
+
});
|
213
|
+
});
|
214
|
+
};
|
215
|
+
var theme = {
|
216
|
+
colors: colorScheme === 'dark' ? darkTheme : lightTheme
|
217
|
+
};
|
218
|
+
return /*#__PURE__*/React.createElement(ThemeContext.Provider, {
|
219
|
+
value: {
|
220
|
+
theme: theme,
|
221
|
+
toggleTheme: toggleTheme
|
222
|
+
}
|
223
|
+
}, children);
|
224
|
+
};
|
225
|
+
|
226
|
+
var ThemeToggle = function ThemeToggle() {
|
227
|
+
var _a = React.useContext(ThemeContext),
|
228
|
+
theme = _a.theme,
|
229
|
+
toggleTheme = _a.toggleTheme;
|
230
|
+
var isDarkMode = theme.colors === darkTheme;
|
231
|
+
return /*#__PURE__*/React.createElement(reactNative.View, {
|
232
|
+
style: styles.container
|
233
|
+
}, /*#__PURE__*/React.createElement(reactNative.Text, {
|
234
|
+
style: [styles.text, {
|
235
|
+
color: theme.colors.text.hex
|
236
|
+
}]
|
237
|
+
}, "Dark Mode"), /*#__PURE__*/React.createElement(reactNative.Switch, {
|
238
|
+
value: isDarkMode,
|
239
|
+
onValueChange: toggleTheme,
|
240
|
+
trackColor: {
|
241
|
+
"false": lightTheme.secondary.hex,
|
242
|
+
"true": darkTheme.primary.hex
|
243
|
+
},
|
244
|
+
thumbColor: isDarkMode ? darkTheme.secondary.hex : lightTheme.primary.hex
|
245
|
+
}));
|
246
|
+
};
|
247
|
+
var styles = reactNative.StyleSheet.create({
|
248
|
+
container: {
|
249
|
+
marginTop: 20,
|
250
|
+
flexDirection: 'row',
|
251
|
+
alignItems: 'center'
|
252
|
+
},
|
253
|
+
text: {
|
254
|
+
marginRight: 10,
|
255
|
+
fontSize: 16
|
256
|
+
}
|
257
|
+
});
|
258
|
+
|
259
|
+
exports.ThemeContext = ThemeContext;
|
260
|
+
exports.ThemeProvider = ThemeProvider;
|
261
|
+
exports.ThemeToggle = ThemeToggle;
|
@@ -0,0 +1,17 @@
|
|
1
|
+
export interface RGB {
|
2
|
+
r: number;
|
3
|
+
g: number;
|
4
|
+
b: number;
|
5
|
+
}
|
6
|
+
export interface Color {
|
7
|
+
hex: string;
|
8
|
+
rgb: RGB;
|
9
|
+
}
|
10
|
+
export interface ThemeColors {
|
11
|
+
primary: Color;
|
12
|
+
secondary: Color;
|
13
|
+
background: Color;
|
14
|
+
text: Color;
|
15
|
+
}
|
16
|
+
export declare const lightTheme: ThemeColors;
|
17
|
+
export declare const darkTheme: ThemeColors;
|
package/index.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export { default as ButtonComponent } from "./src/Button";
|
package/package.json
CHANGED
@@ -1,16 +1,36 @@
|
|
1
1
|
{
|
2
2
|
"name": "aport-tools",
|
3
|
-
"version": "1.0.
|
4
|
-
"description": "",
|
5
|
-
|
3
|
+
"version": "1.0.2",
|
4
|
+
"description": "Aport mobile Tools with modern and minimalistic design",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"type": "module",
|
7
|
+
"react-native": "dist/index.js",
|
8
|
+
"source": "src/index.ts",
|
9
|
+
"types": "dist/index.d.ts",
|
6
10
|
"scripts": {
|
11
|
+
"build": "rollup -c rollup.config.mjs",
|
12
|
+
"prepare": "npm run build",
|
7
13
|
"test": "echo \"Error: no test specified\" && exit 1"
|
8
14
|
},
|
9
|
-
"keywords": [
|
15
|
+
"keywords": [
|
16
|
+
"react-native",
|
17
|
+
"theme",
|
18
|
+
"provider",
|
19
|
+
"context",
|
20
|
+
"toggle",
|
21
|
+
"mobile",
|
22
|
+
"tools"
|
23
|
+
],
|
10
24
|
"author": "EvansGxz",
|
11
25
|
"license": "ISC",
|
12
26
|
"devDependencies": {
|
27
|
+
"@babel/core": "^7.25.2",
|
28
|
+
"@babel/preset-env": "^7.25.4",
|
29
|
+
"@babel/preset-react": "^7.24.7",
|
30
|
+
"@babel/preset-typescript": "^7.24.7",
|
31
|
+
"@rollup/plugin-babel": "^6.0.4",
|
13
32
|
"@rollup/plugin-commonjs": "^28.0.0",
|
33
|
+
"@rollup/plugin-json": "^6.1.0",
|
14
34
|
"@rollup/plugin-node-resolve": "^15.3.0",
|
15
35
|
"@rollup/plugin-typescript": "^12.1.0",
|
16
36
|
"@types/react": "^18.3.10",
|
@@ -20,11 +40,10 @@
|
|
20
40
|
"rollup-plugin-peer-deps-external": "^2.2.4",
|
21
41
|
"typescript": "^5.6.2"
|
22
42
|
},
|
23
|
-
"
|
43
|
+
"peerDependencies": {
|
24
44
|
"@react-native-async-storage/async-storage": "^2.0.0",
|
25
|
-
"
|
26
|
-
"react": "
|
27
|
-
"react-native": "^0.75.3",
|
45
|
+
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
46
|
+
"react-native": ">=0.60",
|
28
47
|
"styled-components": "^6.1.13"
|
29
48
|
}
|
30
49
|
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
// rollup.config.js
|
2
|
+
|
3
|
+
import babel from '@rollup/plugin-babel';
|
4
|
+
import typescript from '@rollup/plugin-typescript';
|
5
|
+
import commonjs from '@rollup/plugin-commonjs';
|
6
|
+
import resolve from '@rollup/plugin-node-resolve';
|
7
|
+
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
|
8
|
+
import pkg from './package.json' assert { type: 'json' };
|
9
|
+
|
10
|
+
export default {
|
11
|
+
input: 'src/index.ts', // Entry point
|
12
|
+
output: [
|
13
|
+
{
|
14
|
+
file: 'dist/index.js',
|
15
|
+
format: 'cjs',
|
16
|
+
name: pkg.name, // Use package name
|
17
|
+
banner: `/*! ${pkg.name} v${pkg.version} | ${pkg.license} */`, // Add banner comment with package info
|
18
|
+
},
|
19
|
+
{
|
20
|
+
file: 'dist/index.es.js',
|
21
|
+
format: 'es',
|
22
|
+
name: pkg.name,
|
23
|
+
banner: `/*! ${pkg.name} v${pkg.version} | ${pkg.license} */`,
|
24
|
+
},
|
25
|
+
],
|
26
|
+
plugins: [
|
27
|
+
peerDepsExternal(),
|
28
|
+
resolve({
|
29
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
30
|
+
}),
|
31
|
+
commonjs(),
|
32
|
+
babel({
|
33
|
+
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
34
|
+
include: ['src/**/*'],
|
35
|
+
babelHelpers: 'bundled',
|
36
|
+
presets: [
|
37
|
+
'@babel/preset-env',
|
38
|
+
'@babel/preset-react',
|
39
|
+
'@babel/preset-typescript',
|
40
|
+
],
|
41
|
+
}),
|
42
|
+
typescript({
|
43
|
+
tsconfig: './tsconfig.json',
|
44
|
+
declaration: true,
|
45
|
+
declarationDir: 'dist',
|
46
|
+
emitDeclarationOnly: false, // Set to true if you want TypeScript to only emit declarations and let Babel handle the JS transpilation
|
47
|
+
}),
|
48
|
+
],
|
49
|
+
external: [
|
50
|
+
'react',
|
51
|
+
'react-native',
|
52
|
+
'@react-native-async-storage/async-storage',
|
53
|
+
'styled-components',
|
54
|
+
], // Dependencies not to bundle
|
55
|
+
};
|
package/rollup.config.js
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
// rollup.config.js
|
2
|
-
|
3
|
-
import typescript from '@rollup/plugin-typescript';
|
4
|
-
import resolve from '@rollup/plugin-node-resolve';
|
5
|
-
import commonjs from '@rollup/plugin-commonjs';
|
6
|
-
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
|
7
|
-
|
8
|
-
export default {
|
9
|
-
input: 'src/index.ts', // Entry point of your library
|
10
|
-
output: [
|
11
|
-
{
|
12
|
-
file: 'dist/index.js', // CommonJS format
|
13
|
-
format: 'cjs',
|
14
|
-
sourcemap: true,
|
15
|
-
},
|
16
|
-
{
|
17
|
-
file: 'dist/index.es.js', // ES Module format
|
18
|
-
format: 'esm',
|
19
|
-
sourcemap: true,
|
20
|
-
},
|
21
|
-
],
|
22
|
-
plugins: [
|
23
|
-
peerDepsExternal(), // Automatically externalize peer dependencies
|
24
|
-
resolve({
|
25
|
-
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
26
|
-
}), // So Rollup can find node_modules
|
27
|
-
commonjs(), // So Rollup can convert commonjs to ES modules
|
28
|
-
typescript({ tsconfig: './tsconfig.json' }), // So Rollup can handle TypeScript
|
29
|
-
],
|
30
|
-
external: ['react', 'react-native'], // Explicitly externalize dependencies
|
31
|
-
};
|
package/src/Button.tsx
DELETED
@@ -1,104 +0,0 @@
|
|
1
|
-
// src/components/Button.tsx
|
2
|
-
|
3
|
-
import React, { useMemo, useContext } from 'react';
|
4
|
-
import { Text, ViewStyle, StyleSheet, TouchableOpacity } from 'react-native';
|
5
|
-
import { ThemeContext } from './context/ThemeContext'; // Adjust path to your ThemeContext
|
6
|
-
import { ThemeColors } from './styles/colors';
|
7
|
-
|
8
|
-
// Define the interface for the props that the Button component will accept
|
9
|
-
interface ButtonProps {
|
10
|
-
disabled?: boolean; // Optional: Disables the button if true
|
11
|
-
isFullWidth?: boolean; // Optional: Expands the button to full width if true
|
12
|
-
children?: string; // Optional: Text content of the button
|
13
|
-
onPress?: () => void; // Optional: Function to call when the button is pressed
|
14
|
-
rounded?: boolean; // Optional: Adds border radius if true
|
15
|
-
borderRadius?: number; // Optional: Custom border radius value
|
16
|
-
type?: 'submit' | 'button' | 'cancel'; // Optional: Specifies the button type for styling
|
17
|
-
}
|
18
|
-
|
19
|
-
// Function to determine the styles based on the button type and whether it is disabled
|
20
|
-
function typeStyles(type?: string, disabled?: boolean, themeColors?: ThemeColors): ViewStyle {
|
21
|
-
switch (type) {
|
22
|
-
case 'submit':
|
23
|
-
return {
|
24
|
-
backgroundColor: `rgba(${themeColors?.primary.rgb.r}, ${themeColors?.primary.rgb.g}, ${themeColors?.primary.rgb.b}, ${
|
25
|
-
disabled ? 0.5 : 1
|
26
|
-
})`,
|
27
|
-
borderWidth: 2,
|
28
|
-
borderColor: themeColors?.primary.hex,
|
29
|
-
};
|
30
|
-
case 'button':
|
31
|
-
return {
|
32
|
-
backgroundColor: themeColors?.primary.hex,
|
33
|
-
borderColor: themeColors?.secondary.hex,
|
34
|
-
opacity: disabled ? 0.5 : 1,
|
35
|
-
borderWidth: 2,
|
36
|
-
};
|
37
|
-
case 'cancel':
|
38
|
-
return {
|
39
|
-
backgroundColor: themeColors?.background.hex,
|
40
|
-
borderWidth: 0,
|
41
|
-
};
|
42
|
-
default:
|
43
|
-
return {};
|
44
|
-
}
|
45
|
-
}
|
46
|
-
|
47
|
-
// Button component definition
|
48
|
-
const Button: React.FC<ButtonProps> = ({
|
49
|
-
children,
|
50
|
-
disabled = false,
|
51
|
-
type = 'button',
|
52
|
-
rounded = true,
|
53
|
-
borderRadius = 30,
|
54
|
-
isFullWidth = false,
|
55
|
-
onPress,
|
56
|
-
}) => {
|
57
|
-
// Access the current theme from ThemeContext
|
58
|
-
const { theme } = useContext(ThemeContext);
|
59
|
-
const { colors } = theme; // Extract colors from the theme
|
60
|
-
|
61
|
-
// Use useMemo to memoize the computed styles
|
62
|
-
const computedStyles = useMemo(() => {
|
63
|
-
return StyleSheet.flatten([
|
64
|
-
styles.button,
|
65
|
-
typeStyles(type, disabled, colors), // Use colors directly
|
66
|
-
rounded && { borderRadius },
|
67
|
-
isFullWidth && { width: '100%' },
|
68
|
-
disabled && styles.disabled,
|
69
|
-
]);
|
70
|
-
}, [type, disabled, rounded, borderRadius, isFullWidth, colors]);
|
71
|
-
|
72
|
-
// Determine text color based on button type and theme
|
73
|
-
const textColor = useMemo(() => {
|
74
|
-
return { color: colors.text.hex }; // Access text color from the theme
|
75
|
-
}, [type, colors]);
|
76
|
-
|
77
|
-
return (
|
78
|
-
<TouchableOpacity
|
79
|
-
style={computedStyles as ViewStyle}
|
80
|
-
disabled={disabled}
|
81
|
-
onPress={onPress}
|
82
|
-
activeOpacity={0.7}
|
83
|
-
>
|
84
|
-
<Text style={textColor}>
|
85
|
-
{Array.isArray(children) ? children.join('').toUpperCase() : children?.toUpperCase()}
|
86
|
-
</Text>
|
87
|
-
</TouchableOpacity>
|
88
|
-
);
|
89
|
-
};
|
90
|
-
|
91
|
-
// Define basic styles for the button
|
92
|
-
const styles = StyleSheet.create({
|
93
|
-
button: {
|
94
|
-
justifyContent: 'center',
|
95
|
-
alignItems: 'center',
|
96
|
-
paddingVertical: 10,
|
97
|
-
paddingHorizontal: 20,
|
98
|
-
},
|
99
|
-
disabled: {
|
100
|
-
opacity: 0.6,
|
101
|
-
},
|
102
|
-
});
|
103
|
-
|
104
|
-
export default Button;
|
@@ -1,39 +0,0 @@
|
|
1
|
-
// src/components/ThemeToggle.tsx
|
2
|
-
|
3
|
-
import React, { useContext } from 'react';
|
4
|
-
import { Switch, View, Text, StyleSheet } from 'react-native';
|
5
|
-
import { ThemeContext } from '../context/ThemeContext';
|
6
|
-
import { darkTheme, lightTheme } from '../styles/colors';
|
7
|
-
|
8
|
-
const ThemeToggle: React.FC = () => {
|
9
|
-
const { theme, toggleTheme } = useContext(ThemeContext);
|
10
|
-
|
11
|
-
// Determine if the current theme is dark by checking the colors property
|
12
|
-
const isDarkMode = theme.colors === darkTheme;
|
13
|
-
|
14
|
-
return (
|
15
|
-
<View style={styles.container}>
|
16
|
-
<Text style={[styles.text, { color: theme.colors.text.hex }]}>Dark Mode</Text>
|
17
|
-
<Switch
|
18
|
-
value={isDarkMode}
|
19
|
-
onValueChange={toggleTheme}
|
20
|
-
trackColor={{ false: lightTheme.secondary.hex, true: darkTheme.primary.hex }}
|
21
|
-
thumbColor={isDarkMode ? darkTheme.secondary.hex : lightTheme.primary.hex}
|
22
|
-
/>
|
23
|
-
</View>
|
24
|
-
);
|
25
|
-
};
|
26
|
-
|
27
|
-
const styles = StyleSheet.create({
|
28
|
-
container: {
|
29
|
-
marginTop: 20,
|
30
|
-
flexDirection: 'row',
|
31
|
-
alignItems: 'center',
|
32
|
-
},
|
33
|
-
text: {
|
34
|
-
marginRight: 10,
|
35
|
-
fontSize: 16,
|
36
|
-
},
|
37
|
-
});
|
38
|
-
|
39
|
-
export default ThemeToggle;
|
@@ -1,70 +0,0 @@
|
|
1
|
-
// src/context/ThemeContext.tsx
|
2
|
-
|
3
|
-
import React, { createContext, useState, useEffect, ReactNode } from 'react';
|
4
|
-
import { Appearance, ColorSchemeName } from 'react-native';
|
5
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
6
|
-
import { lightTheme, darkTheme, ThemeColors } from '../styles/colors';
|
7
|
-
import { Theme } from '../styles/theme';
|
8
|
-
|
9
|
-
interface ThemeContextProps {
|
10
|
-
theme: Theme;
|
11
|
-
toggleTheme: () => void;
|
12
|
-
}
|
13
|
-
|
14
|
-
export const ThemeContext = createContext<ThemeContextProps>({
|
15
|
-
theme: { colors: lightTheme },
|
16
|
-
toggleTheme: () => {},
|
17
|
-
});
|
18
|
-
|
19
|
-
interface ThemeProviderProps {
|
20
|
-
children: ReactNode;
|
21
|
-
}
|
22
|
-
|
23
|
-
export const ThemeProvider: React.FC<ThemeProviderProps> = ({ children }) => {
|
24
|
-
const [colorScheme, setColorScheme] = useState<ColorSchemeName | null>(null);
|
25
|
-
|
26
|
-
useEffect(() => {
|
27
|
-
const loadTheme = async () => {
|
28
|
-
try {
|
29
|
-
const storedTheme = await AsyncStorage.getItem('theme');
|
30
|
-
if (storedTheme === 'dark' || storedTheme === 'light') {
|
31
|
-
setColorScheme(storedTheme);
|
32
|
-
} else {
|
33
|
-
const systemTheme = Appearance.getColorScheme();
|
34
|
-
setColorScheme(systemTheme);
|
35
|
-
}
|
36
|
-
} catch (error) {
|
37
|
-
console.error('Failed to load theme.', error);
|
38
|
-
setColorScheme(Appearance.getColorScheme());
|
39
|
-
}
|
40
|
-
};
|
41
|
-
|
42
|
-
loadTheme();
|
43
|
-
|
44
|
-
const subscription = Appearance.addChangeListener(({ colorScheme }) => {
|
45
|
-
setColorScheme(colorScheme);
|
46
|
-
});
|
47
|
-
|
48
|
-
return () => subscription.remove();
|
49
|
-
}, []);
|
50
|
-
|
51
|
-
const toggleTheme = async () => {
|
52
|
-
try {
|
53
|
-
const newTheme = colorScheme === 'dark' ? 'light' : 'dark';
|
54
|
-
setColorScheme(newTheme);
|
55
|
-
await AsyncStorage.setItem('theme', newTheme);
|
56
|
-
} catch (error) {
|
57
|
-
console.error('Failed to toggle theme.', error);
|
58
|
-
}
|
59
|
-
};
|
60
|
-
|
61
|
-
const theme: Theme = {
|
62
|
-
colors: colorScheme === 'dark' ? darkTheme : lightTheme,
|
63
|
-
};
|
64
|
-
|
65
|
-
return (
|
66
|
-
<ThemeContext.Provider value={{ theme, toggleTheme }}>
|
67
|
-
{children}
|
68
|
-
</ThemeContext.Provider>
|
69
|
-
);
|
70
|
-
};
|
package/src/index.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export { default as ButtonComponent } from "./Button";
|
package/src/styles/colors.ts
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
// src/styles/colors.ts
|
2
|
-
|
3
|
-
export interface RGB {
|
4
|
-
r: number;
|
5
|
-
g: number;
|
6
|
-
b: number;
|
7
|
-
}
|
8
|
-
|
9
|
-
export interface Color {
|
10
|
-
hex: string;
|
11
|
-
rgb: RGB;
|
12
|
-
}
|
13
|
-
|
14
|
-
export interface ThemeColors {
|
15
|
-
primary: Color;
|
16
|
-
secondary: Color;
|
17
|
-
background: Color;
|
18
|
-
text: Color;
|
19
|
-
// Add more categories as needed
|
20
|
-
}
|
21
|
-
|
22
|
-
export const lightTheme: ThemeColors = {
|
23
|
-
primary: {
|
24
|
-
hex: '#1A73E8',
|
25
|
-
rgb: { r: 26, g: 115, b: 232 },
|
26
|
-
},
|
27
|
-
secondary: {
|
28
|
-
hex: '#F0F6FF',
|
29
|
-
rgb: { r: 240, g: 246, b: 255 },
|
30
|
-
},
|
31
|
-
background: {
|
32
|
-
hex: '#FFFFFF',
|
33
|
-
rgb: { r: 255, g: 255, b: 255 },
|
34
|
-
},
|
35
|
-
text: {
|
36
|
-
hex: '#000000',
|
37
|
-
rgb: { r: 0, g: 0, b: 0 },
|
38
|
-
},
|
39
|
-
// Add more categories as needed
|
40
|
-
};
|
41
|
-
|
42
|
-
export const darkTheme: ThemeColors = {
|
43
|
-
primary: {
|
44
|
-
hex: '#BB86FC',
|
45
|
-
rgb: { r: 187, g: 134, b: 252 },
|
46
|
-
},
|
47
|
-
secondary: {
|
48
|
-
hex: '#03DAC6',
|
49
|
-
rgb: { r: 3, g: 218, b: 198 },
|
50
|
-
},
|
51
|
-
background: {
|
52
|
-
hex: '#121212',
|
53
|
-
rgb: { r: 18, g: 18, b: 18 },
|
54
|
-
},
|
55
|
-
text: {
|
56
|
-
hex: '#FFFFFF',
|
57
|
-
rgb: { r: 255, g: 255, b: 255 },
|
58
|
-
},
|
59
|
-
// Add more categories as needed
|
60
|
-
};
|
package/src/styles/theme.ts
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
// src/styles/theme.ts
|
2
|
-
|
3
|
-
import { ThemeColors } from "./colors";
|
4
|
-
|
5
|
-
// Define the light theme with full ThemeColors structure
|
6
|
-
export const lightTheme: ThemeColors = {
|
7
|
-
primary: {
|
8
|
-
hex: "#1A73E8",
|
9
|
-
rgb: { r: 26, g: 115, b: 232 },
|
10
|
-
},
|
11
|
-
secondary: {
|
12
|
-
hex: "#F0F6FF",
|
13
|
-
rgb: { r: 240, g: 246, b: 255 },
|
14
|
-
},
|
15
|
-
background: {
|
16
|
-
hex: "#FFFFFF",
|
17
|
-
rgb: { r: 255, g: 255, b: 255 },
|
18
|
-
},
|
19
|
-
text: {
|
20
|
-
hex: "#000000",
|
21
|
-
rgb: { r: 0, g: 0, b: 0 },
|
22
|
-
},
|
23
|
-
};
|
24
|
-
|
25
|
-
// Define the dark theme with full ThemeColors structure
|
26
|
-
export const darkTheme: ThemeColors = {
|
27
|
-
primary: {
|
28
|
-
hex: "#BB86FC",
|
29
|
-
rgb: { r: 187, g: 134, b: 252 },
|
30
|
-
},
|
31
|
-
secondary: {
|
32
|
-
hex: "#03DAC6",
|
33
|
-
rgb: { r: 3, g: 218, b: 198 },
|
34
|
-
},
|
35
|
-
background: {
|
36
|
-
hex: "#121212",
|
37
|
-
rgb: { r: 18, g: 18, b: 18 },
|
38
|
-
},
|
39
|
-
text: {
|
40
|
-
hex: "#FFFFFF",
|
41
|
-
rgb: { r: 255, g: 255, b: 255 },
|
42
|
-
},
|
43
|
-
};
|
44
|
-
|
45
|
-
// src/styles/theme.ts
|
46
|
-
|
47
|
-
export interface Theme {
|
48
|
-
colors: ThemeColors;
|
49
|
-
}
|
50
|
-
|
package/tsconfig.json
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"compilerOptions": {
|
3
|
-
"outDir": "dist",
|
4
|
-
"module": "ES6",
|
5
|
-
"target": "ES5",
|
6
|
-
"lib": [
|
7
|
-
"ES2015",
|
8
|
-
"DOM"
|
9
|
-
],
|
10
|
-
"jsx": "react-native",
|
11
|
-
"declaration": true,
|
12
|
-
"esModuleInterop": true,
|
13
|
-
"forceConsistentCasingInFileNames": true,
|
14
|
-
"strict": true,
|
15
|
-
"skipLibCheck": true,
|
16
|
-
"moduleResolution": "node",
|
17
|
-
"types": [
|
18
|
-
"react",
|
19
|
-
"react-native"
|
20
|
-
]
|
21
|
-
},
|
22
|
-
"include": [
|
23
|
-
"src" ],
|
24
|
-
"exclude": [
|
25
|
-
"node_modules",
|
26
|
-
"dist",
|
27
|
-
"App.tsx"
|
28
|
-
],
|
29
|
-
"extends": "expo/tsconfig.base"
|
30
|
-
}
|