├── .editorconfig ├── .gitattributes ├── .github ├── actions │ └── setup │ │ └── action.yml └── workflows │ └── ci.yml ├── .gitignore ├── .watchmanconfig ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── babel.config.js ├── example ├── App.js ├── app.json ├── assets │ ├── adaptive-icon.png │ ├── favicon.png │ ├── icon.png │ └── splash.png ├── babel.config.js ├── metro.config.js ├── package.json ├── src │ ├── App.tsx │ ├── HooksExample.tsx │ ├── ReStyleSheetExample.tsx │ ├── responsiveBox.tsx │ └── theme.ts ├── tsconfig.json ├── webpack.config.js └── yarn.lock ├── lefthook.yml ├── package.json ├── scripts └── bootstrap.js ├── src ├── ReStyleSheet.ts ├── __tests__ │ └── index.test.tsx ├── createStore.ts ├── createStyleSheet.ts ├── hooks │ └── useMediaQuery.ts ├── index.tsx ├── mediaQuery.ts ├── multiKeyStore.ts ├── types.ts ├── utill │ ├── addDynamicValue.ts │ ├── getDeviceType.ts │ ├── initializeBreakpoints.ts │ ├── isDynamicValue.ts │ └── shallowEqual.ts └── validations │ └── checkProviderError.ts ├── tsconfig.build.json ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | indent_style = space 10 | indent_size = 2 11 | 12 | end_of_line = lf 13 | charset = utf-8 14 | trim_trailing_whitespace = true 15 | insert_final_newline = true 16 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | # specific for windows script files 3 | *.bat text eol=crlf -------------------------------------------------------------------------------- /.github/actions/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: Setup 2 | description: Setup Node.js and install dependencies 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - name: Setup Node.js 8 | uses: actions/setup-node@v3 9 | with: 10 | node-version-file: .nvmrc 11 | 12 | - name: Cache dependencies 13 | id: yarn-cache 14 | uses: actions/cache@v3 15 | with: 16 | path: | 17 | **/node_modules 18 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 19 | restore-keys: | 20 | ${{ runner.os }}-yarn- 21 | 22 | - name: Install dependencies 23 | if: steps.yarn-cache.outputs.cache-hit != 'true' 24 | run: | 25 | yarn install --cwd example --frozen-lockfile 26 | yarn install --frozen-lockfile 27 | shell: bash 28 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | lint: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@v3 16 | 17 | - name: Setup 18 | uses: ./.github/actions/setup 19 | 20 | - name: Lint files 21 | run: yarn lint 22 | 23 | - name: Typecheck files 24 | run: yarn typecheck 25 | 26 | test: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | 32 | - name: Setup 33 | uses: ./.github/actions/setup 34 | 35 | - name: Run unit tests 36 | run: yarn test --maxWorkers=2 --coverage 37 | 38 | build: 39 | runs-on: ubuntu-latest 40 | steps: 41 | - name: Checkout 42 | uses: actions/checkout@v3 43 | 44 | - name: Setup 45 | uses: ./.github/actions/setup 46 | 47 | - name: Build package 48 | run: yarn prepack 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # XDE 6 | .expo/ 7 | 8 | # VSCode 9 | .vscode/ 10 | jsconfig.json 11 | 12 | # Xcode 13 | # 14 | build/ 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata 24 | *.xccheckout 25 | *.moved-aside 26 | DerivedData 27 | *.hmap 28 | *.ipa 29 | *.xcuserstate 30 | project.xcworkspace 31 | 32 | # Android/IJ 33 | # 34 | .classpath 35 | .cxx 36 | .gradle 37 | .idea 38 | .project 39 | .settings 40 | local.properties 41 | android.iml 42 | 43 | # Cocoapods 44 | # 45 | example/ios/Pods 46 | 47 | # Ruby 48 | example/vendor/ 49 | 50 | # node.js 51 | # 52 | node_modules/ 53 | npm-debug.log 54 | yarn-debug.log 55 | yarn-error.log 56 | 57 | # BUCK 58 | buck-out/ 59 | \.buckd/ 60 | android/app/libs 61 | android/keystores/debug.keystore 62 | 63 | # Expo 64 | .expo/ 65 | 66 | # Turborepo 67 | .turbo/ 68 | 69 | # generated by bob 70 | lib/ 71 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official e-mail address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | [INSERT CONTACT METHOD]. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are always welcome, no matter how large or small! 4 | 5 | We want this community to be friendly and respectful to each other. Please follow it in all your interactions with the project. Before contributing, please read the [code of conduct](./CODE_OF_CONDUCT.md). 6 | 7 | ## Development workflow 8 | 9 | To get started with the project, run `yarn` in the root directory to install the required dependencies for each package: 10 | 11 | ```sh 12 | yarn 13 | ``` 14 | 15 | > While it's possible to use [`npm`](https://github.com/npm/cli), the tooling is built around [`yarn`](https://classic.yarnpkg.com/), so you'll have an easier time if you use `yarn` for development. 16 | 17 | While developing, you can run the [example app](/example/) to test your changes. Any changes you make in your library's JavaScript code will be reflected in the example app without a rebuild. If you change any native code, then you'll need to rebuild the example app. 18 | 19 | To start the packager: 20 | 21 | ```sh 22 | yarn example start 23 | ``` 24 | 25 | To run the example app on Android: 26 | 27 | ```sh 28 | yarn example android 29 | ``` 30 | 31 | To run the example app on iOS: 32 | 33 | ```sh 34 | yarn example ios 35 | ``` 36 | 37 | To run the example app on Web: 38 | 39 | ```sh 40 | yarn example web 41 | ``` 42 | 43 | Make sure your code passes TypeScript and ESLint. Run the following to verify: 44 | 45 | ```sh 46 | yarn typecheck 47 | yarn lint 48 | ``` 49 | 50 | To fix formatting errors, run the following: 51 | 52 | ```sh 53 | yarn lint --fix 54 | ``` 55 | 56 | Remember to add tests for your change if possible. Run the unit tests by: 57 | 58 | ```sh 59 | yarn test 60 | ``` 61 | 62 | 63 | ### Commit message convention 64 | 65 | We follow the [conventional commits specification](https://www.conventionalcommits.org/en) for our commit messages: 66 | 67 | - `fix`: bug fixes, e.g. fix crash due to deprecated method. 68 | - `feat`: new features, e.g. add new method to the module. 69 | - `refactor`: code refactor, e.g. migrate from class components to hooks. 70 | - `docs`: changes into documentation, e.g. add usage example for the module.. 71 | - `test`: adding or updating tests, e.g. add integration tests using detox. 72 | - `chore`: tooling changes, e.g. change CI config. 73 | 74 | Our pre-commit hooks verify that your commit message matches this format when committing. 75 | 76 | ### Linting and tests 77 | 78 | [ESLint](https://eslint.org/), [Prettier](https://prettier.io/), [TypeScript](https://www.typescriptlang.org/) 79 | 80 | We use [TypeScript](https://www.typescriptlang.org/) for type checking, [ESLint](https://eslint.org/) with [Prettier](https://prettier.io/) for linting and formatting the code, and [Jest](https://jestjs.io/) for testing. 81 | 82 | Our pre-commit hooks verify that the linter and tests pass when committing. 83 | 84 | ### Publishing to npm 85 | 86 | We use [release-it](https://github.com/release-it/release-it) to make it easier to publish new versions. It handles common tasks like bumping version based on semver, creating tags and releases etc. 87 | 88 | To publish new versions, run the following: 89 | 90 | ```sh 91 | yarn release 92 | ``` 93 | 94 | ### Scripts 95 | 96 | The `package.json` file contains various scripts for common tasks: 97 | 98 | - `yarn bootstrap`: setup project by installing all dependencies and pods. 99 | - `yarn typecheck`: type-check files with TypeScript. 100 | - `yarn lint`: lint files with ESLint. 101 | - `yarn test`: run unit tests with Jest. 102 | - `yarn example start`: start the Metro server for the example app. 103 | - `yarn example android`: run the example app on Android. 104 | - `yarn example ios`: run the example app on iOS. 105 | 106 | ### Sending a pull request 107 | 108 | > **Working on your first pull request?** You can learn how from this _free_ series: [How to Contribute to an Open Source Project on GitHub](https://app.egghead.io/playlists/how-to-contribute-to-an-open-source-project-on-github). 109 | 110 | When you're sending a pull request: 111 | 112 | - Prefer small pull requests focused on one change. 113 | - Verify that linters and tests are passing. 114 | - Review the documentation to make sure it looks good. 115 | - Follow the pull request template when opening a pull request. 116 | - For pull requests that change the API or implementation, discuss with maintainers first by opening an issue. 117 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 redwanul islam 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![svgviewer-png-output (1)](https://user-images.githubusercontent.com/22383818/224547367-bea84225-e1b9-45cd-aa5d-a59372ba7cb9.jpeg) 2 | 3 | # react-native-restyle-sheet 4 | 5 | [![npm version](https://img.shields.io/npm/v/react-native-restyle-sheet)](https://www.npmjs.com/package/react-native-restyle-sheet) 6 | ![GitHub](https://img.shields.io/github/license/redwanul10/react-native-restyle-sheet) 7 | ![npm](https://img.shields.io/npm/dw/react-native-restyle-sheet) 8 | 9 | restyle-sheet provides flexible way to define Theming, Dynamic styles & Media Query support for React Native 10 | 11 | ## Features 12 | 13 | - Media Query Support 14 | - Easy way to define Dynamic Style & Theming (No inline style) 15 | - useMediaQuery hooks 16 | - Fully typed with TypeScript 17 | 18 | https://user-images.githubusercontent.com/22383818/226711571-9a310e32-7e3d-499c-a04a-898028be49ec.mp4 19 | 20 | ## PlayGround 21 | 22 | Check out the codeSandbox playGround [link](https://codesandbox.io/s/react-native-restyle-sheet-example-vh19ce) 23 | 24 | ## Install 25 | 26 | ```sh 27 | yarn add react-native-restyle-sheet 28 | # or 29 | npm install --save react-native-restyle-sheet 30 | ``` 31 | 32 | ## Usage 33 | 34 | 1. First We need to initialize Style Sheet 35 | 36 | ```js 37 | // theme.js 38 | 39 | import { createStyleSheet } from 'react-native-restyle-sheet'; 40 | 41 | export const lightTheme = { 42 | themeId: 'light', 43 | colors: { 44 | main: 'green', 45 | primary: '#00235B', 46 | secondary: '#E21818', 47 | tertiary: '#FFDD83', 48 | quatenary: '#98DFD6', 49 | }, 50 | }; 51 | 52 | const breakpoints = { 53 | small: 0, 54 | medium: 500, 55 | large: 800, 56 | // you can define custom device size also 57 | }; 58 | 59 | export const { ReStyleSheet, changeTheme } = createStyleSheet({ 60 | theme: lightTheme, 61 | breakpoints, 62 | }); 63 | ``` 64 | 65 | 2. Then use ReStyleSheet like this anywhere in your app with theme & breakpoints: 66 | 67 | ```js 68 | import React from 'react'; 69 | import { View, Text } from 'react-native'; 70 | import { ReStyleSheet } from './theme'; 71 | 72 | const useStyle = ReStyleSheet(({ theme, breakpoints }) => ({ 73 | header: { 74 | fontWeight: 'bold', 75 | fontSize: 20, 76 | color: theme.colors.tertiary, 77 | [breakpoints.only('medium')]: { 78 | color: theme.colors.primary, 79 | }, 80 | }, 81 | })); 82 | 83 | const Demo = () => { 84 | const { styles } = useStyle(); 85 | return ( 86 | <> 87 | 88 | Hello World 89 | 90 | 91 | ); 92 | }; 93 | ``` 94 | 95 | ## Define dynamic style 96 | 97 | we can pass any dynamic values in useStyle hooks returned by ReStyleSheet 98 | 99 | ```js 100 | const useStyle = ReStyleSheet(() => ({ 101 | header: { 102 | fontSize: 20, 103 | color: (props) => props?.activeColor, 104 | }, 105 | })); 106 | 107 | const Demo = () => { 108 | const [color, setColor] = React.useState('red'); 109 | const { styles } = useStyle({ activeColor: color }); 110 | 111 | const toggleColor = () => { 112 | setColor(color === 'red' ? 'green' : 'red'); 113 | }; 114 | 115 | return ( 116 | 117 | Hello World 118 | 119 | Toggle Color 120 | 121 | 122 | ); 123 | }; 124 | ``` 125 | 126 | ## Change Theme 127 | 128 | 1. To change the Theme we can use **`changeTheme()`** method anywhere in our app 129 | 130 | ```js 131 | // theme.js 132 | 133 | import { createStyleSheet } from 'react-native-restyle-sheet'; 134 | 135 | const lightTheme = { 136 | themeId: 'lightTheme', 137 | colors: { 138 | ... 139 | }, 140 | }; 141 | 142 | const darkTheme = { 143 | themeId: 'darkTheme', 144 | colors: { 145 | ... 146 | }, 147 | }; 148 | 149 | const breakpoints = { 150 | ... 151 | }; 152 | 153 | export const { ReStyleSheet, changeTheme } = createStyleSheet({ 154 | theme: lightTheme, 155 | breakpoints, 156 | }); 157 | 158 | export const toggleTheme = () => { 159 | changeTheme((themId) => (themId === 'darkTheme' ? lightTheme : darkTheme)); 160 | }; 161 | 162 | ``` 163 | 164 | 165 | ## Override Media Query 166 | 167 | If multiple breakpoints are applicable similar to css rule the bottom breakpoint will get priority. \ 168 | For example we are in a **"small"** device so here **breakpoints.only('small')** & **breakpoints.down('medium')** both are applicable 169 | 170 | ```js 171 | // Example 1 172 | const useStyle = ReStyleSheet(({ breakpoints }) => ({ 173 | header: { 174 | backgroundColor: 'black', 175 | [breakpoints.only('large')]: { 176 | backgroundColor: 'red', 177 | }, 178 | [breakpoints.only('small')]: { 179 | backgroundColor: 'green', 180 | }, 181 | // in "small" device header background will be "blue" 182 | [breakpoints.down('medium')]: { 183 | backgroundColor: 'blue', 184 | }, 185 | }, 186 | })); 187 | 188 | // Example 2 189 | const useStyle = ReStyleSheet(({ breakpoints }) => ({ 190 | header: { 191 | backgroundColor: 'black', 192 | [breakpoints.only('large')]: { 193 | backgroundColor: 'red', 194 | }, 195 | [breakpoints.down('medium')]: { 196 | backgroundColor: 'blue', 197 | }, 198 | // in "small" device header background will be "green" 199 | [breakpoints.only('small')]: { 200 | backgroundColor: 'green', 201 | }, 202 | }, 203 | })); 204 | ``` 205 | 206 | ## breakpoints API 207 | 208 | 209 | | Methods | Arguments |Required | Returns | 210 | | ------------- |:-------------:| -------------| -------------| 211 | | **`breakpoints.up(size)`** | size (string) |true |MediaQuery key (string) | 212 | | **`breakpoints.down(size)`** | size (string) |true | MediaQuery key (string) | 213 | | **`breakpoints.only(size)`** | size (string) |true | MediaQuery key (string) | 214 | 215 | 216 | 217 | ## useMediaQuery Hooks 218 | 219 | It returns the device size based on breakpoints 220 | 221 | ```js 222 | import { useMediaQuery } from 'react-native-restyle-sheet'; 223 | 224 | const Demo = () => { 225 | const devicetype = useMediaQuery() 226 | console.log(devicetype) // For Example: small 227 | 228 | .... 229 | }; 230 | ``` 231 | 232 | It also accepts custom breakpoints and returns boolean value 233 | 234 | ```js 235 | const isTablet = useMediaQuery({ min: 400, max: 800 }); 236 | const isExtraLarge = useMediaQuery({ min: 1200 }); 237 | const isExtraSmall = useMediaQuery({ Max: 576 }); 238 | 239 | console.log(isTablet); //false 240 | ``` 241 | 271 | 272 | ## License 273 | 274 | MIT 275 | 276 | --- 277 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /example/App.js: -------------------------------------------------------------------------------- 1 | export { default } from './src/App'; 2 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "example", 4 | "slug": "example", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "updates": { 15 | "fallbackToCacheTimeout": 0 16 | }, 17 | "assetBundlePatterns": [ 18 | "**/*" 19 | ], 20 | "ios": { 21 | "supportsTablet": true 22 | }, 23 | "android": { 24 | "adaptiveIcon": { 25 | "foregroundImage": "./assets/adaptive-icon.png", 26 | "backgroundColor": "#FFFFFF" 27 | } 28 | }, 29 | "web": { 30 | "favicon": "./assets/favicon.png" 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redwanul10/react-native-restyle-sheet/6ebae0fae0096e9ba517b5defa82d11f949efc89/example/assets/adaptive-icon.png -------------------------------------------------------------------------------- /example/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redwanul10/react-native-restyle-sheet/6ebae0fae0096e9ba517b5defa82d11f949efc89/example/assets/favicon.png -------------------------------------------------------------------------------- /example/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redwanul10/react-native-restyle-sheet/6ebae0fae0096e9ba517b5defa82d11f949efc89/example/assets/icon.png -------------------------------------------------------------------------------- /example/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redwanul10/react-native-restyle-sheet/6ebae0fae0096e9ba517b5defa82d11f949efc89/example/assets/splash.png -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = function (api) { 5 | api.cache(true); 6 | 7 | return { 8 | presets: ['babel-preset-expo'], 9 | plugins: [ 10 | [ 11 | 'module-resolver', 12 | { 13 | extensions: ['.tsx', '.ts', '.js', '.json'], 14 | alias: { 15 | // For development, we want to alias the library to the source 16 | [pak.name]: path.join(__dirname, '..', pak.source), 17 | }, 18 | }, 19 | ], 20 | ], 21 | }; 22 | }; 23 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const escape = require('escape-string-regexp'); 3 | const { getDefaultConfig } = require('@expo/metro-config'); 4 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 5 | const pak = require('../package.json'); 6 | 7 | const root = path.resolve(__dirname, '..'); 8 | 9 | const modules = Object.keys({ 10 | ...pak.peerDependencies, 11 | }); 12 | 13 | const defaultConfig = getDefaultConfig(__dirname); 14 | 15 | module.exports = { 16 | ...defaultConfig, 17 | 18 | projectRoot: __dirname, 19 | watchFolders: [root], 20 | 21 | // We need to make sure that only one version is loaded for peerDependencies 22 | // So we block them at the root, and alias them to the versions in example's node_modules 23 | resolver: { 24 | ...defaultConfig.resolver, 25 | 26 | blacklistRE: exclusionList( 27 | modules.map( 28 | (m) => 29 | new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`) 30 | ) 31 | ), 32 | 33 | extraNodeModules: modules.reduce((acc, name) => { 34 | acc[name] = path.join(__dirname, 'node_modules', name); 35 | return acc; 36 | }, {}), 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "node_modules/expo/AppEntry.js", 5 | "scripts": { 6 | "start": "expo start", 7 | "android": "expo start --android", 8 | "ios": "expo start --ios", 9 | "web": "expo start --web" 10 | }, 11 | "dependencies": { 12 | "@types/react": "~18.0.24", 13 | "@types/react-native": "~0.70.6", 14 | "expo": "~47.0.12", 15 | "expo-status-bar": "~1.4.2", 16 | "react": "18.1.0", 17 | "react-dom": "18.1.0", 18 | "react-native": "0.70.5", 19 | "react-native-web": "~0.18.9", 20 | "typescript": "^4.6.3" 21 | }, 22 | "devDependencies": { 23 | "@babel/core": "^7.12.9", 24 | "@expo/webpack-config": "^0.17.2", 25 | "babel-loader": "^8.1.0", 26 | "babel-plugin-module-resolver": "^4.1.0" 27 | }, 28 | "private": true 29 | } 30 | -------------------------------------------------------------------------------- /example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | import { SafeAreaView } from 'react-native'; 4 | import HooksExample from './HooksExample'; 5 | import ResponsiveBox from './responsiveBox'; 6 | import ReStyleSheetExample from './ReStyleSheetExample'; 7 | 8 | export default function App() { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /example/src/HooksExample.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Text, View } from 'react-native'; 3 | import { useMediaQuery } from 'react-native-restyle-sheet'; 4 | import { ReStyleSheet } from './theme'; 5 | 6 | const useStyle = ReStyleSheet(() => ({ 7 | container: { 8 | backgroundColor: 'green', 9 | width: 250, 10 | height: 100, 11 | marginTop: 30, 12 | justifyContent: 'center', 13 | alignItems: 'center', 14 | alignSelf: 'center', 15 | borderRadius: 20, 16 | }, 17 | paragraph: { 18 | fontWeight: 'bold', 19 | fontSize: 20, 20 | color: 'white', 21 | }, 22 | })); 23 | 24 | export default function HooksExample() { 25 | const { styles } = useStyle(); 26 | const size = useMediaQuery(); 27 | return ( 28 | 29 | from Hooks {size} 30 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /example/src/ReStyleSheetExample.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button, Text } from 'react-native'; 3 | import { ReStyleSheet, toggleTheme } from './theme'; 4 | 5 | const useStyle = ReStyleSheet(({ theme, breakpoints }) => ({ 6 | title: { 7 | fontWeight: 'bold', 8 | fontSize: 25, 9 | marginVertical: 16, 10 | backgroundColor: theme.colors.primary, 11 | color: 'white', 12 | textAlign: 'center', 13 | [breakpoints.only('large')]: { 14 | backgroundColor: 'green', 15 | }, 16 | }, 17 | subtitle: { 18 | fontWeight: 'bold', 19 | fontSize: 25, 20 | textAlign: 'center', 21 | color: (props) => props.activeColor, 22 | }, 23 | })); 24 | 25 | export default function ReStyleSheetExample() { 26 | const [color, setColor] = React.useState('#DF2E38'); 27 | const { styles, deviceType } = useStyle({ activeColor: color }, true); 28 | 29 | const isLargeDevice = deviceType === 'large'; 30 | 31 | const toggleColor = () => { 32 | setColor(color === '#DF2E38' ? 'black' : '#DF2E38'); 33 | }; 34 | 35 | return ( 36 | <> 37 | React Native 38 | re-size codesandbox window 39 | 40 | Device size {deviceType} 41 | {isLargeDevice && ( 42 | only visible for large device 43 | )} 44 | 45 |