Skip to content

Commit 86ad14b

Browse files
authored
Merge pull request #17 from mohit23x/enhancement
Enhancement
2 parents 5ba0c61 + bd2e768 commit 86ad14b

16 files changed

Lines changed: 143 additions & 116 deletions

README.md

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ https://www.npmjs.com/package/react-native-sugar-style (🧪 Experimental)
1313

1414
| BEFORE | AFTER |
1515
| ------------------------------------- | ---------------------------------- |
16-
| ![Before](assets/before.png 'Before') | ![After](assets/after.png 'After') |
16+
| ![Before](assets/before.png "Before") | ![After](assets/after.png "After") |
1717

1818
### Install
1919

@@ -32,16 +32,16 @@ STEP 1: **style.tsx**
3232
Define configurations for your theme, for more verbose example see [this file](https://github.com/mohit23x/react-native-sugar-style/blob/main/example/style/index.tsx).
3333

3434
```typescript
35-
import Sugar from 'react-native-sugar-style';
35+
import Sugar from "react-native-sugar-style";
3636

3737
const dark = {
38-
background: '#2b2b2b',
39-
text: '#ffffff',
38+
background: "#2b2b2b",
39+
text: "#ffffff",
4040
};
4141

4242
const light = {
43-
background: '#fbfbfb',
44-
text: '#000000',
43+
background: "#fbfbfb",
44+
text: "#000000",
4545
};
4646

4747
export const { StyleSheet, ThemeProvider, useTheme } = Sugar(light);
@@ -74,9 +74,9 @@ STEP 3: **component.tsx**
7474
Use StyleSheet as you do normally do in components
7575

7676
```javascript
77-
import React from 'react';
78-
import { View, Text } from 'react-native';
79-
import { StyleSheet, useTheme } from './style';
77+
import React from "react";
78+
import { View, Text } from "react-native";
79+
import { StyleSheet, useTheme } from "./style";
8080

8181
const Component = () => {
8282
useTheme();
@@ -93,7 +93,7 @@ const styles = StyleSheet.create((theme, constants) => ({
9393
height: constants.height,
9494
width: constants.width,
9595
backgroundColor: theme.background,
96-
flexDirection: ['column', 'row'],
96+
flexDirection: ["column", "row"],
9797
},
9898
text: {
9999
fontSize: theme.size.m,
@@ -111,9 +111,9 @@ STEP 4: **anotherComponent.tsx**
111111
To change the theme you can call build method and it will swap the theme
112112

113113
```javascript
114-
import React from 'react';
115-
import { View, Button } from 'react-native';
116-
import { StyleSheet, light, dark } from './style';
114+
import React from "react";
115+
import { View, Button } from "react-native";
116+
import { StyleSheet, light, dark } from "./style";
117117

118118
const Component = () => {
119119
const onLight = () => StyleSheet.build(light);
@@ -133,24 +133,23 @@ const Component = () => {
133133
Scan and run with expo go app, run the [example project](https://github.com/mohit23x/react-native-sugar-style/tree/main/example) for a more detailed example.
134134
https://expo.io/@mohit23x/projects/react-native-sugar-style or try the [react native web version](https://sugar-style.netlify.app/)
135135

136-
![Scan QR with expo app](assets/qr.png 'Scan QR')
136+
![Scan QR with expo app](assets/qr.png "Scan QR")
137137

138138
### Constants
139139

140140
Available as **theme.constant**
141141

142-
| Name | Type | React Native way |
143-
| -------------------------------------- | ------- | ------------------------------------------ |
144-
| height | number | const {height} = Dimensions.get('window'); |
145-
| width | number | const {width} = Dimensions.get('window'); |
146-
| screenHeight | number | const {height} = Dimensions.get('screen'); |
147-
| screenWidth | number | const {width} = Dimensions.get('screen'); |
148-
| statusBarHeight | number | StatusBar.currentHeight |
149-
| navBarHeight | number | screenHeight - statusBarHeight - height |
150-
| isNavBarVisible | boolean | bottom navigation is visible or not |
151-
| visibleHeight | number | height - navBarHeight |
152-
| isIPhoneX | boolean | |
153-
| platform: {android, ios, windows, web} | boolean | Platform.OS === 'android' |
142+
| Name | Type | React Native way |
143+
| ------------------------------------------------------------- | ------- | ------------------------------------------ |
144+
| height | number | const {height} = Dimensions.get('window'); |
145+
| width | number | const {width} = Dimensions.get('window'); |
146+
| screenHeight | number | const {height} = Dimensions.get('screen'); |
147+
| screenWidth | number | const {width} = Dimensions.get('screen'); |
148+
| statusBarHeight | number | StatusBar.currentHeight |
149+
| navBarHeight | number | screenHeight - statusBarHeight - height |
150+
| isNavBarVisible | boolean | bottom navigation is visible or not |
151+
| visibleHeight | number | height - navBarHeight |
152+
| platform: {android, ios, windows, web, isPad, isTv,isIPhoneX} | boolean | Platform.OS === 'android' |
154153

155154
### Why this package?
156155

build/Constant.d.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,14 @@ export declare const constants: {
1515
readonly navBarHeight: number;
1616
readonly isNavBarVisible: boolean;
1717
readonly visibleHeight: number;
18-
readonly isIPhoneX: () => boolean;
19-
readonly os: {
18+
readonly platform: {
2019
readonly android: boolean;
2120
readonly ios: boolean;
2221
readonly web: boolean;
2322
readonly windows: boolean;
23+
readonly isPad: boolean;
24+
readonly isTv: boolean;
25+
readonly isIPhoneX: () => boolean;
2426
};
2527
readonly breakPoints: {
2628
mobile: number;

build/Constant.js

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
Object.defineProperty(exports, "__esModule", { value: true });
33
exports.constants = exports.calculateVisibleHeight = exports.calculateNavBarHeight = void 0;
44
const react_native_1 = require("react-native");
5-
const { height, width } = react_native_1.Dimensions.get('window');
5+
const { height, width } = react_native_1.Dimensions.get("window");
66
/* =========== */
77
// code credits: https://medium.com/codespace69/reactnative-ios-android-detect-screen-notch-status-bar-device-info-dc11b8c6a6a3
88
const X_WIDTH = 375;
99
const X_HEIGHT = 812;
1010
const XSMAX_WIDTH = 414;
1111
const XSMAX_HEIGHT = 896;
12-
const isIPhoneX = () => react_native_1.Platform.OS === 'ios' && !react_native_1.Platform.isPad && !react_native_1.Platform.isTVOS
12+
const isIPhoneX = () => react_native_1.Platform.OS === "ios" && !react_native_1.Platform.isPad && !react_native_1.Platform.isTVOS
1313
? (width === X_WIDTH && height === X_HEIGHT) ||
1414
(width === XSMAX_WIDTH && height === XSMAX_HEIGHT)
1515
: false;
@@ -19,22 +19,27 @@ const statusBarHeight = react_native_1.Platform.select({
1919
default: 0,
2020
});
2121
/* ====== x ====== */
22-
const { height: screenHeight, width: screenWidth } = react_native_1.Dimensions.get('screen');
23-
exports.calculateNavBarHeight = ({ screenHeight, height, }) => {
22+
const { height: screenHeight, width: screenWidth } = react_native_1.Dimensions.get("screen");
23+
const calculateNavBarHeight = ({ screenHeight, height, }) => {
2424
return screenHeight - statusBarHeight - height;
2525
};
26+
exports.calculateNavBarHeight = calculateNavBarHeight;
2627
const navBarHeight = exports.calculateNavBarHeight({
2728
screenHeight,
2829
height,
2930
});
3031
const isNavBarVisible = navBarHeight > 0;
31-
exports.calculateVisibleHeight = ({ height, navBarHeight, }) => height - navBarHeight;
32+
const calculateVisibleHeight = ({ height, navBarHeight, }) => height - navBarHeight;
33+
exports.calculateVisibleHeight = calculateVisibleHeight;
3234
const visibleHeight = exports.calculateVisibleHeight({ height, navBarHeight });
33-
const os = {
34-
android: react_native_1.Platform.OS === 'android',
35-
ios: react_native_1.Platform.OS === 'ios',
36-
web: react_native_1.Platform.OS === 'web',
37-
windows: react_native_1.Platform.OS === 'windows',
35+
const platform = {
36+
android: react_native_1.Platform.OS === "android",
37+
ios: react_native_1.Platform.OS === "ios",
38+
web: react_native_1.Platform.OS === "web",
39+
windows: react_native_1.Platform.OS === "windows",
40+
isPad: react_native_1.Platform.OS === "ios" ? react_native_1.Platform.isPad : false,
41+
isTv: react_native_1.Platform.isTV,
42+
isIPhoneX,
3843
};
3944
const breakPoints = {
4045
mobile: 480,
@@ -50,7 +55,6 @@ exports.constants = {
5055
navBarHeight,
5156
isNavBarVisible,
5257
visibleHeight,
53-
isIPhoneX,
54-
os,
58+
platform,
5559
breakPoints,
5660
};

build/Main.d.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ export default function Main<T>(theme: T): {
1313
readonly navBarHeight: number;
1414
readonly isNavBarVisible: boolean;
1515
readonly visibleHeight: number;
16-
readonly isIPhoneX: () => boolean;
17-
readonly os: {
16+
readonly platform: {
1817
readonly android: boolean;
1918
readonly ios: boolean;
2019
readonly web: boolean;
2120
readonly windows: boolean;
21+
readonly isPad: boolean;
22+
readonly isTv: boolean;
23+
readonly isIPhoneX: () => boolean;
2224
};
2325
readonly breakPoints: {
2426
mobile: number;
@@ -27,10 +29,7 @@ export default function Main<T>(theme: T): {
2729
};
2830
};
2931
}>;
30-
ThemeProvider: import("react").ComponentType<{
31-
children: import("react").ReactNode;
32-
sugar?: Sugar<T> | undefined;
33-
}>;
32+
ThemeProvider: import("./type").ThemeProviderType<T>;
3433
useTheme: () => ({
3534
readonly height: number;
3635
readonly width: number;
@@ -40,12 +39,14 @@ export default function Main<T>(theme: T): {
4039
readonly navBarHeight: number;
4140
readonly isNavBarVisible: boolean;
4241
readonly visibleHeight: number;
43-
readonly isIPhoneX: () => boolean;
44-
readonly os: {
42+
readonly platform: {
4543
readonly android: boolean;
4644
readonly ios: boolean;
4745
readonly web: boolean;
4846
readonly windows: boolean;
47+
readonly isPad: boolean;
48+
readonly isTv: boolean;
49+
readonly isIPhoneX: () => boolean;
4950
};
5051
readonly breakPoints: {
5152
mobile: number;

build/Provider.d.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
import * as React from 'react';
22
import Sugar from './Sugar';
3-
import type { ThemeProp, ConstantsType } from './type';
3+
import type { ConstantsType, ThemeProp, ThemeProviderType } from './type';
44
export declare function themeCreator<T>(sugar: Sugar<T>, defaultTheme: T): {
55
ThemeContext: React.Context<{
66
theme: T;
77
constants: ConstantsType;
88
}>;
9-
ThemeProvider: React.ComponentType<{
10-
children: React.ReactNode;
11-
sugar?: Sugar<T> | undefined;
12-
}>;
9+
ThemeProvider: ThemeProviderType<T>;
1310
useTheme: () => ({
1411
readonly height: number;
1512
readonly width: number;
@@ -19,12 +16,14 @@ export declare function themeCreator<T>(sugar: Sugar<T>, defaultTheme: T): {
1916
readonly navBarHeight: number;
2017
readonly isNavBarVisible: boolean;
2118
readonly visibleHeight: number;
22-
readonly isIPhoneX: () => boolean;
23-
readonly os: {
19+
readonly platform: {
2420
readonly android: boolean;
2521
readonly ios: boolean;
2622
readonly web: boolean;
2723
readonly windows: boolean;
24+
readonly isPad: boolean;
25+
readonly isTv: boolean;
26+
readonly isIPhoneX: () => boolean;
2827
};
2928
readonly breakPoints: {
3029
mobile: number;

build/Provider.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ function createThemeProvider(sugar, ThemeContext, defaultTheme) {
99
const ThemeProvider = ({ children, }) => {
1010
const [theme, setTheme] = React.useState(defaultTheme);
1111
const [constants, setConstants] = React.useState(Constant_1.constants);
12+
const onBuild = () => {
13+
setTheme(sugar.theme);
14+
setConstants(sugar.constants);
15+
};
1216
const subscribeToThemeChanges = () => {
13-
sugar.subscribe('build', () => {
14-
setTheme(sugar.theme);
15-
setConstants(sugar.constants);
16-
});
17+
sugar.subscribe('build', onBuild);
1718
};
1819
const onDimensionChange = ({ window: { height, width }, screen: { height: screenHeight, width: screenWidth }, }) => {
1920
const navBarHeight = Constant_1.calculateNavBarHeight({
@@ -39,6 +40,7 @@ function createThemeProvider(sugar, ThemeContext, defaultTheme) {
3940
subscribeToDimensionsChange();
4041
return () => {
4142
react_native_1.Dimensions.removeEventListener('change', onDimensionChange);
43+
sugar.unsubscribe('build', onBuild);
4244
};
4345
}, []);
4446
return (<ThemeContext.Provider value={{ theme, constants }}>{children}</ThemeContext.Provider>);
@@ -57,9 +59,9 @@ function themeCreator(sugar, defaultTheme) {
5759
return function WithTheme() {
5860
return (<ThemeContext.Consumer>
5961
{({ theme, constants }) => {
60-
const props = { theme, constants };
61-
return <WrappedComponent {...props}/>;
62-
}}
62+
const props = { theme, constants };
63+
return <WrappedComponent {...props}/>;
64+
}}
6365
</ThemeContext.Consumer>);
6466
};
6567
}

build/Sugar.d.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { StyleSheet } from 'react-native';
2-
import { Fn, buildEventType, NamedStyles, ConstantsType, StyleSheetType } from './type';
3-
import Sheet from './Sheet';
1+
import { StyleSheet } from "react-native";
2+
import Sheet from "./Sheet";
3+
import { BuildEventType, ConstantsType, Fn, NamedStyles, StyleSheetType } from "./type";
44
export default class Sugar<T> {
55
builded: boolean;
66
theme: T;
@@ -99,10 +99,11 @@ export default class Sugar<T> {
9999
_refresh(): void;
100100
build(themeObj: T): void;
101101
configure(newConstants: Partial<ConstantsType>): void;
102-
create<P extends NamedStyles<P> | NamedStyles<any>>(objFn: Fn<T, P> | P): StyleSheetType<P>;
102+
create<P extends NamedStyles<P> | NamedStyles<any>>(objFn: Fn<T, P> | P): P extends NamedStyles<P> ? StyleSheetType<P> : P;
103103
_calculateActiveIndex(): void;
104104
_calcSheets(): void;
105-
_callListeners(event: buildEventType): void;
106-
subscribe(event: buildEventType, listener: () => any): void;
107-
_assertSubscriptionParams(event: buildEventType, listener: any): void;
105+
_callListeners(event: BuildEventType): void;
106+
subscribe(event: BuildEventType, listener: () => any): void;
107+
unsubscribe(event: BuildEventType, listener: () => any): void;
108+
_assertSubscriptionParams(event: BuildEventType, listener: any): void;
108109
}

build/Sugar.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use strict";
22
Object.defineProperty(exports, "__esModule", { value: true });
33
const react_native_1 = require("react-native");
4-
const Sheet_1 = require("./Sheet");
54
const Constant_1 = require("./Constant");
6-
const BUILD_EVENT = 'build';
5+
const Sheet_1 = require("./Sheet");
6+
const BUILD_EVENT = "build";
77
class Sugar {
88
constructor(newTheme) {
99
this.builded = true;
@@ -35,7 +35,7 @@ class Sugar {
3535
this._refresh();
3636
}
3737
create(objFn) {
38-
if (typeof objFn === 'function') {
38+
if (typeof objFn === "function") {
3939
const sheet = new Sheet_1.default(objFn);
4040
this.sheets.push(sheet);
4141
if (this.builded) {
@@ -72,12 +72,18 @@ class Sugar {
7272
listener();
7373
}
7474
}
75+
unsubscribe(event, listener) {
76+
this._assertSubscriptionParams(event, listener);
77+
if (this.listeners[BUILD_EVENT]) {
78+
this.listeners[BUILD_EVENT].filter((item) => item !== listener);
79+
}
80+
}
7581
_assertSubscriptionParams(event, listener) {
7682
if (event !== BUILD_EVENT) {
7783
throw new Error(`Only '${BUILD_EVENT}' event is currently supported.`);
7884
}
79-
if (typeof listener !== 'function') {
80-
throw new Error('Listener should be a function.');
85+
if (typeof listener !== "function") {
86+
throw new Error("Listener should be a function.");
8187
}
8288
}
8389
}

build/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
77
o[k2] = m[k];
88
}));
99
var __exportStar = (this && this.__exportStar) || function(m, exports) {
10-
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
10+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
1111
};
1212
Object.defineProperty(exports, "__esModule", { value: true });
1313
exports.Sugar = void 0;

build/type.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ export declare type NamedStyles<T> = {
1616
[P in keyof T]: SugarViewStyle | SugarTextStyle | SugarImageStyle;
1717
};
1818
export declare type S = NamedStyles<any>;
19-
export declare type Fn<T, P> = (theme: T, constants: ConstantsType) => P extends NamedStyles<P> ? NamedStyles<P> : P;
19+
export declare type Fn<T, P> = (theme: T, constants: ConstantsType) => P;
2020
export declare type StyleSheetType<P> = {
2121
[K in keyof P]: {
2222
[J in keyof P[K]]: P[K][J] extends Array<any> ? J extends 'transform' | 'transformMatrix' ? P[K][J] : P[K][J][number] : P[K][J];
2323
};
2424
};
25-
export declare type buildEventType = 'build';
25+
export declare type BuildEventType = 'build';
2626
export declare type ThemeProp<T> = {
2727
theme: T;
2828
constants: ConstantsType;

0 commit comments

Comments
 (0)