aport-tools 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/app.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "aport-tools",
3
+ "displayName": "Aport Tools"
4
+ }
5
+
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "aport-tools",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "EvansGxz",
11
+ "license": "ISC",
12
+ "devDependencies": {
13
+ "@rollup/plugin-commonjs": "^28.0.0",
14
+ "@rollup/plugin-node-resolve": "^15.3.0",
15
+ "@rollup/plugin-typescript": "^12.1.0",
16
+ "@types/react": "^18.3.10",
17
+ "@types/react-native": "^0.73.0",
18
+ "@types/styled-components-react-native": "^5.2.5",
19
+ "rollup": "^4.22.5",
20
+ "rollup-plugin-peer-deps-external": "^2.2.4",
21
+ "typescript": "^5.6.2"
22
+ },
23
+ "dependencies": {
24
+ "@react-native-async-storage/async-storage": "^2.0.0",
25
+ "expo": "^51.0.34",
26
+ "react": "^18.3.1",
27
+ "react-native": "^0.75.3",
28
+ "styled-components": "^6.1.13"
29
+ }
30
+ }
@@ -0,0 +1,31 @@
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 ADDED
@@ -0,0 +1,104 @@
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;
@@ -0,0 +1,39 @@
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;
@@ -0,0 +1,70 @@
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 ADDED
@@ -0,0 +1 @@
1
+ export { default as ButtonComponent } from "./Button";
@@ -0,0 +1,60 @@
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
+ };
@@ -0,0 +1,50 @@
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 ADDED
@@ -0,0 +1,30 @@
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
+ }