├── .gitignore ├── LICENSE ├── README.md ├── library ├── .npmignore ├── package.json ├── src │ ├── context.tsx │ ├── darklify-stylesheet.ts │ ├── darklify-value.ts │ ├── index.ts │ ├── types.ts │ └── use-darklify-mode.ts └── tsconfig.json ├── package.json ├── tsconfig.base.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | dist/ 59 | 60 | example/.vscode/ 61 | 62 | library/README.md 63 | 64 | Pods/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Admir Šaheta 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | image 2 | 3 |
4 |

Darklify

5 |

Change the way you percieve and work with dark theme in react-native

6 |
7 | 8 | ## Installation 9 | To start using ```darklify``` please verify your version of ```react-native``` is ```0.63.3``` or higher. 10 | ``` 11 | npm i darklify 12 | ``` 13 | 14 | ## About 15 | Darklify was made possible to avoid boring boilerplaiting of ```useColorScheme()``` in react-native. Written in Typescript with full types-support utilising the POP architecture. 16 | 17 | ## How do I use it ? 18 | 19 | ### Hooks 20 | ```useDarklifyMode()``` 21 | Example usage 22 | ```ts 23 | import { useDarklifyMode } from 'darklify' 24 | 25 | function Component() { 26 | const darkModeEnabled = useDarklifyMode() 27 | return 28 | } 29 | ``` 30 | ```useDarklifyValue()``` 31 | Step into the world of Darklify, where each Dynamic keyword takes on the mystique of Darklify. Witness the logos transcend from the brilliance of light to the depths of shadow, guided by the whispers of the theme. Allow your interface to be a canvas of enchantment, where elements shift and change, responding to the captivating allure of the current theme. 32 | ```ts 33 | import { DarklifyValue, useDarklifyValue } from 'react-native-darklify' 34 | 35 | const luminaryLightLogo = require('./light.png') 36 | const obsidianDarkLogo = require('./dark.png') 37 | const logoMetamorphosis = new DarklifyValue(luminaryLightLogo, obsidianDarkLogo) 38 | 39 | function Insignia() { 40 | const essence = useDarklifyValue(logoMetamorphosis) 41 | return 42 | } 43 | ``` 44 | 45 | ### Helper Classes 46 | ```DarklifyValue``` 47 | Crafted to seamlessly intertwine with DarklifyStylesheet and wield the power of useDarklifyValue. Immerse yourself in its brilliance: furnish the first argument to orchestrate a symphony with your light color palette, while the second argument conducts a mesmerizing dance within the depths of your dark color scheme. Unleash the magic that transcends mere styling and elevates your design to an enchanting crescendo. 48 | ```ts 49 | import { DarklifyValue } from 'darklify' 50 | 51 | // Unveil a canvas of wonder, where colors transcend time 52 | const mysticalBackdrop = new DarklifyValue('white', 'black') 53 | ``` 54 | 55 | ### Custom Stylesheet 56 | Unveil the art of Darklify, where code becomes an incantation and your interface dances with shadows: 57 | 58 | 59 | ```ts 60 | import { DarklifyStyleSheet, DarklifyValue, useDarklifyValue } from 'darklify' 61 | 62 | const darklifiedStyles = new DarklifyStyleSheet({ 63 | container: { 64 | backgroundColor: new DarklifyValue('white', 'black'), 65 | flex: 1, 66 | }, 67 | text: { 68 | color: new DarklifyValue('black', 'white'), 69 | textAlign: 'center', 70 | }, 71 | }) 72 | 73 | function EnchantedComponent() { 74 | const styles = useDarklifyValue(darklifiedStyles) 75 | 76 | return ( 77 | 78 | Whispers in the Void 79 | 80 | ) 81 | } 82 | ``` 83 | 84 | ### Providers 85 | Embark on a journey through the tapestry of themes with a touch of enchantment of each component: 86 | ```ts 87 | import { ColorSchemeProvider } from 'darklify' 88 | 89 | function EnchantedScreen() { 90 | return ( 91 | <> 92 | {/* Immerse in the shadows of the dark theme */} 93 | 94 | 95 | 96 | 97 | {/* Bask in the radiance of the light theme */} 98 | 99 | 100 | 101 | 102 | {/* Dance with the spirits of the current theme */} 103 | 104 | 105 | ) 106 | } 107 | ``` 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /library/.npmignore: -------------------------------------------------------------------------------- 1 | tsconfig.json 2 | -------------------------------------------------------------------------------- /library/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "darklify", 3 | "version": "1.0.0", 4 | "main": "./dist/index.js", 5 | "typings": "./dist/index.d.ts", 6 | "repository": "", 7 | "author": "Admir Saheta (https://admirsaheta.com)", 8 | "description": "Helping you build an easier dark-mode experience in React Native", 9 | "license": "MIT", 10 | "scripts": { 11 | "prepublishOnly": "yarn run clean && yarn run build", 12 | "clean": "npx rimraf dist", 13 | "build": "tsc", 14 | "watch": "yarn run build --watch" 15 | }, 16 | "peerDependencies": { 17 | "react": "^16.11.0", 18 | "react-native": "^0.62.0" 19 | }, 20 | "dependencies": { 21 | "@types/react": "*", 22 | "@types/react-native": ">=0.62.0", 23 | "toolkit.ts": "^0.0.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /library/src/context.tsx: -------------------------------------------------------------------------------- 1 | import React, { createContext, useContext, ReactNode } from 'react'; 2 | import { useColorScheme } from 'react-native'; 3 | import { Mode } from './types'; 4 | 5 | 6 | export const ColorSchemeContext = createContext(undefined); 7 | ColorSchemeContext.displayName = 'ColorSchemeContext'; 8 | 9 | abstract class ColorSchemeProviderBase { 10 | protected abstract getContextValue(): Mode; 11 | 12 | public abstract useColorSchemeContext(): Mode; 13 | 14 | public provide(children: ReactNode) { 15 | const contextValue = this.getContextValue(); 16 | return ( 17 | 18 | {children} 19 | 20 | ); 21 | } 22 | } 23 | 24 | class ColorSchemeProvider extends ColorSchemeProviderBase { 25 | constructor(private mode?: Mode) { 26 | super(); 27 | } 28 | 29 | protected getContextValue(): Mode { 30 | return this.mode || (useColorScheme() as Mode) || 'light'; 31 | } 32 | 33 | public useColorSchemeContext(): Mode { 34 | const context = useContext(ColorSchemeContext); 35 | return context || (useColorScheme() as Mode) || 'light'; 36 | } 37 | } 38 | 39 | export const DarkModeContext = ColorSchemeContext; 40 | export const DarkModeProvider = ColorSchemeProvider; 41 | 42 | export function useColorSchemeContext(): Mode { 43 | return DarkModeProvider.prototype.useColorSchemeContext.call(null); 44 | } 45 | 46 | export const useDarkModeContext = useColorSchemeContext; 47 | -------------------------------------------------------------------------------- /library/src/darklify-stylesheet.ts: -------------------------------------------------------------------------------- 1 | import { StyleSheet, ViewStyle, TextStyle, ImageStyle } from 'react-native'; 2 | import { IndexedObject, ValueOf } from 'toolkit.ts'; 3 | import { DarklifyValue, useDarklifyValue } from './darklify-value'; 4 | import { Mode } from './types'; 5 | 6 | declare const process: { 7 | env: { 8 | NODE_ENV: string; 9 | }; 10 | }; 11 | 12 | type Style = ViewStyle | TextStyle | ImageStyle; 13 | 14 | type DarklifyStyle = { [Key in keyof T]: T[Key] | DarklifyValue }; 15 | type DarklifyStyles = { [P in keyof T]: DarklifyStyle