@crystin001/theme-settings-lib 1.0.0
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/README.md +368 -0
- package/dist/color-utils.d.ts +24 -0
- package/dist/color-utils.d.ts.map +1 -0
- package/dist/color-utils.js +104 -0
- package/dist/hooks/use-theme-color.d.ts +15 -0
- package/dist/hooks/use-theme-color.d.ts.map +1 -0
- package/dist/hooks/use-theme-color.js +34 -0
- package/dist/hooks/use-translation.d.ts +10 -0
- package/dist/hooks/use-translation.d.ts.map +1 -0
- package/dist/hooks/use-translation.js +16 -0
- package/dist/i18n.d.ts +23 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +76 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/settings-context.d.ts +24 -0
- package/dist/settings-context.d.ts.map +1 -0
- package/dist/settings-context.js +144 -0
- package/dist/theme.d.ts +49 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +447 -0
- package/package.json +56 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme and Settings Library
|
|
3
|
+
*
|
|
4
|
+
* A reusable library for theme management, settings, and internationalization
|
|
5
|
+
* that can be shared across multiple mobile applications.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { SettingsProvider, useTheme, useTranslation } from '@crystin001/theme-settings-lib';
|
|
10
|
+
*
|
|
11
|
+
* function App() {
|
|
12
|
+
* return (
|
|
13
|
+
* <SettingsProvider>
|
|
14
|
+
* <YourApp />
|
|
15
|
+
* </SettingsProvider>
|
|
16
|
+
* );
|
|
17
|
+
* }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export * from './theme';
|
|
21
|
+
export * from './settings-context';
|
|
22
|
+
export * from './i18n';
|
|
23
|
+
export * from './hooks/use-theme-color';
|
|
24
|
+
export * from './hooks/use-translation';
|
|
25
|
+
export * from './color-utils';
|
|
26
|
+
export { default as i18n } from './i18n';
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,cAAc,SAAS,CAAC;AAGxB,cAAc,oBAAoB,CAAC;AAGnC,cAAc,QAAQ,CAAC;AAGvB,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,eAAe,CAAC;AAG9B,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,QAAQ,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Theme and Settings Library
|
|
4
|
+
*
|
|
5
|
+
* A reusable library for theme management, settings, and internationalization
|
|
6
|
+
* that can be shared across multiple mobile applications.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```tsx
|
|
10
|
+
* import { SettingsProvider, useTheme, useTranslation } from '@crystin001/theme-settings-lib';
|
|
11
|
+
*
|
|
12
|
+
* function App() {
|
|
13
|
+
* return (
|
|
14
|
+
* <SettingsProvider>
|
|
15
|
+
* <YourApp />
|
|
16
|
+
* </SettingsProvider>
|
|
17
|
+
* );
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
24
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
25
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
26
|
+
}
|
|
27
|
+
Object.defineProperty(o, k2, desc);
|
|
28
|
+
}) : (function(o, m, k, k2) {
|
|
29
|
+
if (k2 === undefined) k2 = k;
|
|
30
|
+
o[k2] = m[k];
|
|
31
|
+
}));
|
|
32
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
33
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
34
|
+
};
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.i18n = void 0;
|
|
40
|
+
// Theme exports
|
|
41
|
+
__exportStar(require("./theme"), exports);
|
|
42
|
+
// Settings context exports
|
|
43
|
+
__exportStar(require("./settings-context"), exports);
|
|
44
|
+
// i18n exports
|
|
45
|
+
__exportStar(require("./i18n"), exports);
|
|
46
|
+
// Hook exports
|
|
47
|
+
__exportStar(require("./hooks/use-theme-color"), exports);
|
|
48
|
+
__exportStar(require("./hooks/use-translation"), exports);
|
|
49
|
+
// Utility exports
|
|
50
|
+
__exportStar(require("./color-utils"), exports);
|
|
51
|
+
// Re-export i18n instance for apps that need direct access
|
|
52
|
+
var i18n_1 = require("./i18n");
|
|
53
|
+
Object.defineProperty(exports, "i18n", { enumerable: true, get: function () { return __importDefault(i18n_1).default; } });
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { ThemeName, ThemeFamily } from './theme';
|
|
3
|
+
import { SUPPORTED_LANGUAGES, SupportedLanguage } from './i18n';
|
|
4
|
+
export type { SupportedLanguage, ThemeName, ThemeFamily };
|
|
5
|
+
interface ThemeFamilyInfo {
|
|
6
|
+
family: ThemeFamily;
|
|
7
|
+
label: string;
|
|
8
|
+
lightTheme: ThemeName;
|
|
9
|
+
darkTheme: ThemeName;
|
|
10
|
+
}
|
|
11
|
+
interface SettingsContextType {
|
|
12
|
+
selectedThemeFamily: ThemeFamily;
|
|
13
|
+
currentTheme: ThemeName;
|
|
14
|
+
setThemeFamily: (family: ThemeFamily) => void;
|
|
15
|
+
language: SupportedLanguage;
|
|
16
|
+
setLanguage: (lang: SupportedLanguage) => void;
|
|
17
|
+
availableLanguages: typeof SUPPORTED_LANGUAGES;
|
|
18
|
+
availableThemeFamilies: ThemeFamilyInfo[];
|
|
19
|
+
}
|
|
20
|
+
export declare function SettingsProvider({ children }: {
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
}): React.JSX.Element;
|
|
23
|
+
export declare function useSettings(): SettingsContextType;
|
|
24
|
+
//# sourceMappingURL=settings-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-context.d.ts","sourceRoot":"","sources":["../src/settings-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAkD,SAAS,EAAE,MAAM,OAAO,CAAC;AAGzF,OAAO,EAAE,SAAS,EAAE,WAAW,EAAU,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGhE,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AAE1D,UAAU,eAAe;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,SAAS,CAAC;IACtB,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,UAAU,mBAAmB;IAC3B,mBAAmB,EAAE,WAAW,CAAC;IACjC,YAAY,EAAE,SAAS,CAAC;IACxB,cAAc,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC9C,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,WAAW,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC/C,kBAAkB,EAAE,OAAO,mBAAmB,CAAC;IAC/C,sBAAsB,EAAE,eAAe,EAAE,CAAC;CAC3C;AAoBD,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,qBAuFrE;AAED,wBAAgB,WAAW,wBAM1B"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.SettingsProvider = SettingsProvider;
|
|
40
|
+
exports.useSettings = useSettings;
|
|
41
|
+
const react_1 = __importStar(require("react"));
|
|
42
|
+
const react_native_1 = require("react-native");
|
|
43
|
+
const async_storage_1 = __importDefault(require("@react-native-async-storage/async-storage"));
|
|
44
|
+
const i18n_1 = require("./i18n");
|
|
45
|
+
const i18n_2 = __importDefault(require("./i18n"));
|
|
46
|
+
const SettingsContext = (0, react_1.createContext)(undefined);
|
|
47
|
+
const STORAGE_KEYS = {
|
|
48
|
+
THEME_NAME: '@app/theme_name',
|
|
49
|
+
LANGUAGE: '@app/language',
|
|
50
|
+
};
|
|
51
|
+
const THEME_FAMILY_LABELS = {
|
|
52
|
+
system: 'System',
|
|
53
|
+
'neon-surf': 'Neon Surf',
|
|
54
|
+
'pink-purple': 'Pink & Purple',
|
|
55
|
+
pastel: 'Pastel',
|
|
56
|
+
github: 'GitHub',
|
|
57
|
+
'high-contrast': 'High Contrast',
|
|
58
|
+
solarized: 'Solarized',
|
|
59
|
+
'dark-plus': 'Dark Plus',
|
|
60
|
+
};
|
|
61
|
+
function SettingsProvider({ children }) {
|
|
62
|
+
const systemColorScheme = (0, react_native_1.useColorScheme)();
|
|
63
|
+
const [themeFamily, setThemeFamilyState] = (0, react_1.useState)('system');
|
|
64
|
+
const [language, setLanguageState] = (0, react_1.useState)('en-US');
|
|
65
|
+
// Load settings from storage on mount
|
|
66
|
+
(0, react_1.useEffect)(() => {
|
|
67
|
+
const loadSettings = async () => {
|
|
68
|
+
try {
|
|
69
|
+
const [savedThemeFamily, savedLanguage] = await Promise.all([
|
|
70
|
+
async_storage_1.default.getItem(STORAGE_KEYS.THEME_NAME),
|
|
71
|
+
async_storage_1.default.getItem(STORAGE_KEYS.LANGUAGE),
|
|
72
|
+
]);
|
|
73
|
+
if (savedThemeFamily) {
|
|
74
|
+
const family = savedThemeFamily;
|
|
75
|
+
if (Object.keys(THEME_FAMILY_LABELS).includes(family)) {
|
|
76
|
+
setThemeFamilyState(family);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (savedLanguage) {
|
|
80
|
+
const lang = savedLanguage;
|
|
81
|
+
setLanguageState(lang);
|
|
82
|
+
i18n_2.default.changeLanguage(lang);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.warn('Failed to load settings:', error);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
loadSettings();
|
|
90
|
+
}, []);
|
|
91
|
+
// Calculate the actual theme to use based on current selection
|
|
92
|
+
const getEffectiveTheme = () => {
|
|
93
|
+
if (themeFamily === 'system') {
|
|
94
|
+
return (systemColorScheme || 'light') === 'dark' ? 'system-dark' : 'system-light';
|
|
95
|
+
}
|
|
96
|
+
const variant = (systemColorScheme || 'light') === 'dark' ? 'dark' : 'light';
|
|
97
|
+
return `${themeFamily}-${variant}`;
|
|
98
|
+
};
|
|
99
|
+
const currentTheme = getEffectiveTheme();
|
|
100
|
+
const setThemeFamily = async (family) => {
|
|
101
|
+
try {
|
|
102
|
+
setThemeFamilyState(family);
|
|
103
|
+
await async_storage_1.default.setItem(STORAGE_KEYS.THEME_NAME, family);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.warn('Failed to save theme:', error);
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
// Create theme family info
|
|
110
|
+
const availableThemeFamilies = Object.keys(THEME_FAMILY_LABELS).map((family) => ({
|
|
111
|
+
family,
|
|
112
|
+
label: THEME_FAMILY_LABELS[family],
|
|
113
|
+
lightTheme: family === 'system' ? 'system-light' : `${family}-light`,
|
|
114
|
+
darkTheme: family === 'system' ? 'system-dark' : `${family}-dark`,
|
|
115
|
+
}));
|
|
116
|
+
const setLanguage = async (lang) => {
|
|
117
|
+
try {
|
|
118
|
+
setLanguageState(lang);
|
|
119
|
+
i18n_2.default.changeLanguage(lang);
|
|
120
|
+
await async_storage_1.default.setItem(STORAGE_KEYS.LANGUAGE, lang);
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.warn('Failed to save language:', error);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
return (<SettingsContext.Provider value={{
|
|
127
|
+
selectedThemeFamily: themeFamily,
|
|
128
|
+
currentTheme,
|
|
129
|
+
setThemeFamily,
|
|
130
|
+
language,
|
|
131
|
+
setLanguage,
|
|
132
|
+
availableLanguages: i18n_1.SUPPORTED_LANGUAGES,
|
|
133
|
+
availableThemeFamilies,
|
|
134
|
+
}}>
|
|
135
|
+
{children}
|
|
136
|
+
</SettingsContext.Provider>);
|
|
137
|
+
}
|
|
138
|
+
function useSettings() {
|
|
139
|
+
const context = (0, react_1.useContext)(SettingsContext);
|
|
140
|
+
if (context === undefined) {
|
|
141
|
+
throw new Error('useSettings must be used within a SettingsProvider');
|
|
142
|
+
}
|
|
143
|
+
return context;
|
|
144
|
+
}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme system with theme families that have light and dark variants
|
|
3
|
+
* Each theme family has both a light and dark mode
|
|
4
|
+
*/
|
|
5
|
+
export type ThemeFamily = 'system' | 'neon-surf' | 'pink-purple' | 'pastel' | 'github' | 'high-contrast' | 'solarized' | 'dark-plus';
|
|
6
|
+
export type ThemeVariant = 'light' | 'dark';
|
|
7
|
+
export type ThemeName = `${ThemeFamily}-${ThemeVariant}` | 'system';
|
|
8
|
+
export type ActualThemeName = Exclude<ThemeName, 'system'>;
|
|
9
|
+
export interface ThemeColors {
|
|
10
|
+
text: string;
|
|
11
|
+
background: string;
|
|
12
|
+
tint: string;
|
|
13
|
+
icon: string;
|
|
14
|
+
tabIconDefault: string;
|
|
15
|
+
tabIconSelected: string;
|
|
16
|
+
border: string;
|
|
17
|
+
card: string;
|
|
18
|
+
cardText: string;
|
|
19
|
+
button: string;
|
|
20
|
+
buttonText: string;
|
|
21
|
+
buttonSecondary: string;
|
|
22
|
+
buttonSecondaryText: string;
|
|
23
|
+
input: string;
|
|
24
|
+
inputText: string;
|
|
25
|
+
inputBorder: string;
|
|
26
|
+
success: string;
|
|
27
|
+
warning: string;
|
|
28
|
+
error: string;
|
|
29
|
+
info: string;
|
|
30
|
+
primary: string;
|
|
31
|
+
secondary: string;
|
|
32
|
+
muted: string;
|
|
33
|
+
}
|
|
34
|
+
export declare const Themes: Record<ActualThemeName, ThemeColors>;
|
|
35
|
+
export declare const Colors: {
|
|
36
|
+
light: ThemeColors;
|
|
37
|
+
dark: ThemeColors;
|
|
38
|
+
};
|
|
39
|
+
export declare const Fonts: {
|
|
40
|
+
/** iOS `UIFontDescriptorSystemDesignDefault` */
|
|
41
|
+
sans: string;
|
|
42
|
+
/** iOS `UIFontDescriptorSystemDesignSerif` */
|
|
43
|
+
serif: string;
|
|
44
|
+
/** iOS `UIFontDescriptorSystemDesignRounded` */
|
|
45
|
+
rounded: string;
|
|
46
|
+
/** iOS `UIFontDescriptorSystemDesignMonospaced` */
|
|
47
|
+
mono: string;
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,WAAW,GACX,aAAa,GACb,QAAQ,GACR,QAAQ,GACR,eAAe,GACf,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC;AAE5C,MAAM,MAAM,SAAS,GAAG,GAAG,WAAW,IAAI,YAAY,EAAE,GAAG,QAAQ,CAAC;AAEpE,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAE3D,MAAM,WAAW,WAAW;IAE1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IAExB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,WAAW,CAyZvD,CAAC;AAGF,eAAO,MAAM,MAAM;;;CAGlB,CAAC;AAEF,eAAO,MAAM,KAAK;IAEd,gDAAgD;;IAEhD,8CAA8C;;IAE9C,gDAAgD;;IAEhD,mDAAmD;;CAerD,CAAC"}
|