@codeandmoney/soelma 0.0.0-dev.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.
Files changed (111) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc.js +31 -0
  3. package/.github/workflows/nodejs.yml +33 -0
  4. package/.size-limit.json +6 -0
  5. package/CHANGELOG.md +90 -0
  6. package/LICENSE +21 -0
  7. package/README.md +169 -0
  8. package/babel.config.js +3 -0
  9. package/docs/api.md +103 -0
  10. package/docs/appearance.md +54 -0
  11. package/docs/dark-mode.md +46 -0
  12. package/docs/dimensions.md +29 -0
  13. package/docs/i18n.md +67 -0
  14. package/docs/logo.png +0 -0
  15. package/docs/media-query.md +274 -0
  16. package/docs/orientation.md +44 -0
  17. package/docs/safe-area.md +62 -0
  18. package/docs/testting.md +51 -0
  19. package/docs/ts.md +127 -0
  20. package/example/AppStyleX/.watchmanconfig +1 -0
  21. package/example/AppStyleX/android/build.gradle +26 -0
  22. package/example/AppStyleX/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  23. package/example/AppStyleX/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  24. package/example/AppStyleX/android/gradle.properties +53 -0
  25. package/example/AppStyleX/android/gradlew +249 -0
  26. package/example/AppStyleX/android/gradlew.bat +92 -0
  27. package/example/AppStyleX/android/settings.gradle +12 -0
  28. package/example/AppStyleX/app.json +28 -0
  29. package/example/AppStyleX/babel.config.js +3 -0
  30. package/example/AppStyleX/index.js +9 -0
  31. package/example/AppStyleX/ios/Podfile +7 -0
  32. package/example/AppStyleX/ios/Podfile.lock +1252 -0
  33. package/example/AppStyleX/metro.config.js +54 -0
  34. package/example/AppStyleX/package.json +43 -0
  35. package/example/AppStyleX/react-native.config.js +23 -0
  36. package/example/AppStyleX/src/App.tsx +25 -0
  37. package/example/AppStyleX/src/BottomNav/index.tsx +32 -0
  38. package/example/AppStyleX/src/BottomNav/styles.ts +42 -0
  39. package/example/AppStyleX/src/Circle/index.tsx +53 -0
  40. package/example/AppStyleX/src/Circle/styles.ts +22 -0
  41. package/example/AppStyleX/src/Root/index.tsx +41 -0
  42. package/example/AppStyleX/src/Root/styles.ts +18 -0
  43. package/example/AppStyleX/src/ToggleButton/index.tsx +66 -0
  44. package/example/AppStyleX/src/ToggleButton/styles.ts +69 -0
  45. package/example/AppStyleX/src/style-system/hooks/useAnimatedBgColor.ts +5 -0
  46. package/example/AppStyleX/src/style-system/hooks/useAnimatedTextColor.ts +5 -0
  47. package/example/AppStyleX/src/style-system/hooks/useIsDark.ts +8 -0
  48. package/example/AppStyleX/src/style-system/palette.ts +11 -0
  49. package/example/AppStyleX/src/style-system/theme.ts +14 -0
  50. package/example/AppStyleX/src/style-system/utils.ts +11 -0
  51. package/example/AppStyleX/src/stylex.d.ts +6 -0
  52. package/example/AppStyleX/tsconfig.json +3 -0
  53. package/example/AppStyleX/yarn.lock +6767 -0
  54. package/jest.config.js +19 -0
  55. package/package.json +59 -0
  56. package/src/DefaultTheme.ts +4 -0
  57. package/src/__tests__/createBreakpoints.test.ts +152 -0
  58. package/src/__tests__/createBreakpointsMatcher.test.ts +188 -0
  59. package/src/__tests__/createBreakpointsMatcher.types-test.ts +81 -0
  60. package/src/__tests__/createEventEmitter.test.ts +37 -0
  61. package/src/__tests__/dark-mode.test.ts +56 -0
  62. package/src/__tests__/dependencyRegistry.test.ts +16 -0
  63. package/src/__tests__/dependencyUsage.test.ts +13 -0
  64. package/src/__tests__/dimensions.test.ts +36 -0
  65. package/src/__tests__/makeUseStyles.types-test.ts +69 -0
  66. package/src/__tests__/media-query.test.ts +204 -0
  67. package/src/__tests__/orientation.test.ts +61 -0
  68. package/src/__tests__/useTheme.test.ts +26 -0
  69. package/src/__tests__/withStyles.types-test.tsx +173 -0
  70. package/src/appearance/consts.ts +1 -0
  71. package/src/appearance/index.ts +37 -0
  72. package/src/appearance/init.ts +12 -0
  73. package/src/context.ts +9 -0
  74. package/src/createEventEmitter.ts +26 -0
  75. package/src/dark-mode/consts.ts +1 -0
  76. package/src/dark-mode/index.ts +29 -0
  77. package/src/dark-mode/init.ts +19 -0
  78. package/src/dark-mode/state.ts +5 -0
  79. package/src/dependencyRegistry.ts +21 -0
  80. package/src/dependencyUsage.ts +31 -0
  81. package/src/dimensions/consts.ts +2 -0
  82. package/src/dimensions/index.ts +20 -0
  83. package/src/dimensions/init.ts +37 -0
  84. package/src/dimensions/utils.ts +11 -0
  85. package/src/i18n.ts +18 -0
  86. package/src/index.ts +7 -0
  87. package/src/makeUseStyles/createUseStylesTheme.js +42 -0
  88. package/src/makeUseStyles/createUseStylesTheme.test.js +137 -0
  89. package/src/makeUseStyles/createUseStylesWithoutTheme.js +38 -0
  90. package/src/makeUseStyles/createUseStylesWithoutTheme.test.js +63 -0
  91. package/src/makeUseStyles/index.d.ts +7 -0
  92. package/src/makeUseStyles/index.js +12 -0
  93. package/src/makeUseStyles/index.test.js +28 -0
  94. package/src/makeUseStyles/test-type.js +28 -0
  95. package/src/makeUseStyles/utils.js +67 -0
  96. package/src/media-query/base.ts +43 -0
  97. package/src/media-query/breakpoints.ts +121 -0
  98. package/src/media-query/index.ts +12 -0
  99. package/src/orientation.ts +17 -0
  100. package/src/safe-area/SafeAreaProvider.tsx +17 -0
  101. package/src/safe-area/StylexSaveAreaConsumer.ts +23 -0
  102. package/src/safe-area/consts.ts +1 -0
  103. package/src/safe-area/eventEmitter.ts +4 -0
  104. package/src/safe-area/index.tsx +16 -0
  105. package/src/safe-area/init.tsx +6 -0
  106. package/src/safe-area/state.ts +12 -0
  107. package/src/safe-area/types.ts +10 -0
  108. package/src/useColorTransition.ts +50 -0
  109. package/src/useTheme.ts +16 -0
  110. package/src/withStyles.tsx +35 -0
  111. package/tsconfig.json +30 -0
@@ -0,0 +1,121 @@
1
+ import { minAspectRatio, minWidth, minHeight, maxWidth } from "./base";
2
+
3
+ interface BreakpointsMatcher<TBreakpoints> {
4
+ <T>(values: { [mode in keyof TBreakpoints]?: T }): T | undefined;
5
+ <T>(values: { [mode in keyof TBreakpoints]?: T } & { default: T }): T;
6
+ }
7
+
8
+ const orderByMin = [minWidth, minAspectRatio, minHeight];
9
+
10
+ const toOrderedBreakpointNames = <TBreakpoints extends Record<string, number>>(
11
+ values: any,
12
+ breakpoints: any,
13
+ matchFunction: any
14
+ ): Array<keyof TBreakpoints> => {
15
+ const result = Object.keys(values)
16
+ .filter((e) => e !== "default")
17
+ .sort((a, b) => breakpoints[a] - breakpoints[b]);
18
+
19
+ if (orderByMin.includes(matchFunction)) {
20
+ return result.slice().reverse();
21
+ }
22
+
23
+ return result;
24
+ };
25
+
26
+ /*
27
+ * To debug use analog on CSS: https://codepen.io/retyui/pen/dyOzKzV
28
+ */
29
+ export function createBreakpointsMatcher<
30
+ TBreakpoints extends Record<string, number>
31
+ >(
32
+ breakpoints: TBreakpoints,
33
+ matchFunction = minWidth
34
+ ): BreakpointsMatcher<TBreakpoints> {
35
+ return function breakpointsMatcher(values: any) {
36
+ /* istanbul ignore next */
37
+ // @ts-expect-error: was removed
38
+ if (process.env.NODE_ENV !== "production") {
39
+ const invalidKeys = Object.keys(values).filter((key) => {
40
+ return key !== "default" && breakpoints[key] === undefined;
41
+ });
42
+
43
+ if (invalidKeys.length > 0) {
44
+ console.warn(
45
+ `[react-native-stylex]: Invalid values was passed to 'breakpointsMatcher' function
46
+
47
+ allowed keys: ${Object.keys(breakpoints).join(", ")}
48
+ unexpected keys: ${invalidKeys.join(", ")}
49
+ `
50
+ );
51
+ }
52
+ }
53
+
54
+ const orderedBreakpointNames = toOrderedBreakpointNames<TBreakpoints>(
55
+ values,
56
+ breakpoints,
57
+ matchFunction
58
+ );
59
+
60
+ const key =
61
+ orderedBreakpointNames.find((breakpointName) =>
62
+ matchFunction(
63
+ breakpoints[breakpointName] as number,
64
+ values[breakpointName]
65
+ )
66
+ ) || "default";
67
+
68
+ return values[key] || null;
69
+ };
70
+ }
71
+
72
+ function getNextByKey<TBreakpoints extends Record<string, number>>(
73
+ breakpoints: TBreakpoints,
74
+ key: keyof TBreakpoints
75
+ ) {
76
+ type Keys = keyof TBreakpoints;
77
+
78
+ const breakpointsKeys: Array<Keys> = Object.keys(breakpoints).sort(
79
+ (a: Keys, b: Keys) => breakpoints[a]! - breakpoints[b]!
80
+ );
81
+ const index = breakpointsKeys.indexOf(key);
82
+ const nextKey: Keys | undefined = breakpointsKeys[index + 1];
83
+
84
+ return nextKey;
85
+ }
86
+
87
+ export function createBreakpoints<TBreakpoints extends Record<string, number>>(
88
+ breakpoints: TBreakpoints
89
+ ) {
90
+ type Keys = keyof TBreakpoints;
91
+
92
+ function up<T>(key: Keys, value: T): T | null {
93
+ return minWidth<T>(breakpoints[key] as number, value);
94
+ }
95
+
96
+ function down<T>(key: Keys, value: T): T | null {
97
+ return maxWidth<T>(breakpoints[key] as number, value);
98
+ }
99
+
100
+ function only<T>(key: Keys, value: T): T | null {
101
+ const nextKey = getNextByKey<TBreakpoints>(breakpoints, key);
102
+
103
+ if (nextKey !== undefined) {
104
+ return minWidth(
105
+ breakpoints[key] as number,
106
+ maxWidth(breakpoints[nextKey]! - 0.05, value)
107
+ );
108
+ }
109
+
110
+ return minWidth(breakpoints[key] as number, value);
111
+ }
112
+
113
+ function between<T>(start: Keys, end: Keys, value: T): T | null {
114
+ return minWidth(
115
+ breakpoints[start] as number,
116
+ maxWidth(breakpoints[end]! - 0.05, value)
117
+ );
118
+ }
119
+
120
+ return { up, down, only, between };
121
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ minWidth,
3
+ minAspectRatio,
4
+ maxWidth,
5
+ aspectRatio,
6
+ createDimensionQueryHelper,
7
+ maxAspectRatio,
8
+ maxHeight,
9
+ minHeight,
10
+ } from "./base";
11
+
12
+ export { createBreakpointsMatcher, createBreakpoints } from "./breakpoints";
@@ -0,0 +1,17 @@
1
+ import { getScreenDimensions } from "./dimensions";
2
+
3
+ type OrientationType = "portrait" | "landscape";
4
+
5
+ export function orientation<T>(
6
+ spec: { [orientation in OrientationType]?: T }
7
+ ): T | undefined {
8
+ const { height, width } = getScreenDimensions();
9
+
10
+ return width <= height ? spec.portrait : spec.landscape;
11
+ }
12
+
13
+ export const portraitOrientation = <T>(portraitStyles: T): T | undefined =>
14
+ orientation<T>({ portrait: portraitStyles });
15
+
16
+ export const landscapeOrientation = <T>(landscapeStyles: T): T | undefined =>
17
+ orientation<T>({ landscape: landscapeStyles });
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import { SafeAreaProvider as CoreSafeAreaProvider, initialWindowMetrics,initialWindowSafeAreaInsets } from "react-native-safe-area-context";
3
+
4
+ import { StylexSaveAreaConsumer } from "./StylexSaveAreaConsumer";
5
+ import { SafeAreaViewProps } from "./types";
6
+
7
+ export function SafeAreaProvider(props: SafeAreaViewProps): JSX.Element | null {
8
+ return (
9
+ <CoreSafeAreaProvider
10
+ initialSafeAreaInsets={props.initialSafeAreaInsets || initialWindowSafeAreaInsets}
11
+ initialMetrics={props.initialMetrics || initialWindowMetrics}
12
+ {...props}>
13
+ {props.children}
14
+ <StylexSaveAreaConsumer />
15
+ </CoreSafeAreaProvider>
16
+ );
17
+ }
@@ -0,0 +1,23 @@
1
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
2
+ import { EdgeInsets } from "./types";
3
+
4
+ import { emit } from "./eventEmitter";
5
+ import { state } from "./state";
6
+ import { useLayoutEffect } from "react";
7
+
8
+ export function StylexSaveAreaConsumer(): JSX.Element | null {
9
+ const insets: EdgeInsets = useSafeAreaInsets();
10
+
11
+ useLayoutEffect(() => {
12
+ const isChanged = Object.entries(insets).some(
13
+ ([key, value]) => state.insets[key as keyof EdgeInsets] !== value
14
+ );
15
+
16
+ if (isChanged) {
17
+ state.insets = insets;
18
+ emit();
19
+ }
20
+ }, [insets]);
21
+
22
+ return null;
23
+ }
@@ -0,0 +1 @@
1
+ export const SAFE_AREA_DEPENDENCY_KEY = "react-native-safe-area-context";
@@ -0,0 +1,4 @@
1
+ import { createEventEmitter } from "../createEventEmitter";
2
+ import { SAFE_AREA_DEPENDENCY_KEY } from "./consts";
3
+
4
+ export const { emit, on } = createEventEmitter(SAFE_AREA_DEPENDENCY_KEY);
@@ -0,0 +1,16 @@
1
+ import "./init";
2
+
3
+ import { onUse } from "../dependencyUsage";
4
+
5
+ import { SAFE_AREA_DEPENDENCY_KEY } from "./consts";
6
+ import { EdgeInsets } from "./types";
7
+ import { state } from "./state";
8
+
9
+ export { StylexSaveAreaConsumer } from "./StylexSaveAreaConsumer";
10
+ export { SafeAreaProvider } from "./SafeAreaProvider";
11
+
12
+ export function getSafeArea(): EdgeInsets {
13
+ onUse(SAFE_AREA_DEPENDENCY_KEY);
14
+
15
+ return state.insets;
16
+ }
@@ -0,0 +1,6 @@
1
+ import { addDependency } from "../dependencyRegistry";
2
+
3
+ import { SAFE_AREA_DEPENDENCY_KEY } from "./consts";
4
+ import { on } from "./eventEmitter";
5
+
6
+ addDependency(SAFE_AREA_DEPENDENCY_KEY, (handler: () => void) => on(handler));
@@ -0,0 +1,12 @@
1
+ import { initialWindowMetrics as metrics } from "react-native-safe-area-context";
2
+
3
+ const defaultInsets = {
4
+ top: 0,
5
+ left: 0,
6
+ bottom: 0,
7
+ right: 0,
8
+ };
9
+
10
+ export const state = {
11
+ insets: metrics?.insets || defaultInsets,
12
+ };
@@ -0,0 +1,10 @@
1
+ import {SafeAreaProviderProps} from "react-native-safe-area-context";
2
+
3
+ export interface EdgeInsets {
4
+ top: number;
5
+ right: number;
6
+ bottom: number;
7
+ left: number;
8
+ }
9
+
10
+ export interface SafeAreaViewProps extends SafeAreaProviderProps { }
@@ -0,0 +1,50 @@
1
+ import { useEffect, useMemo, useRef } from "react";
2
+ import { Animated } from "react-native";
3
+ import { DefaultTheme } from "./DefaultTheme";
4
+ import { useTheme } from "./useTheme";
5
+
6
+ const { Value, timing } = Animated;
7
+
8
+ const INITIAL_VALUE = 0;
9
+ const defaultOptions = { duration: 250 };
10
+
11
+ export function useColorTransition<Theme = DefaultTheme>(
12
+ colorGetterFn: (theme: Theme) => string,
13
+ options = defaultOptions
14
+ ): Animated.AnimatedInterpolation<string> {
15
+ const theme = useTheme<Theme>();
16
+ const currentColor = colorGetterFn(theme);
17
+ const animatedValue = useRef(new Value(INITIAL_VALUE));
18
+ const colors = useRef({
19
+ toValue: INITIAL_VALUE,
20
+ prev: currentColor,
21
+ current: currentColor,
22
+ });
23
+
24
+ if (currentColor !== colors.current.current) {
25
+ colors.current = {
26
+ toValue: colors.current.toValue === 0 ? 1 : 0,
27
+ prev: colors.current.current,
28
+ current: currentColor,
29
+ };
30
+ }
31
+
32
+ const { toValue, prev, current } = colors.current;
33
+
34
+ useEffect(() => {
35
+ timing(animatedValue.current, {
36
+ toValue,
37
+ useNativeDriver: false,
38
+ ...options,
39
+ }).start();
40
+ }, [toValue]);
41
+
42
+ return useMemo(() => {
43
+ const outputRange = toValue === 1 ? [prev, current] : [current, prev];
44
+
45
+ return animatedValue.current.interpolate({
46
+ inputRange: [0, 1],
47
+ outputRange,
48
+ });
49
+ }, [prev, current]);
50
+ }
@@ -0,0 +1,16 @@
1
+ import { useContext } from "react";
2
+
3
+ import { themeContext } from "./context";
4
+ import type { DefaultTheme } from "./DefaultTheme";
5
+
6
+ export const useTheme = <Theme = DefaultTheme>(): Theme => {
7
+ const contextValue = useContext(themeContext);
8
+
9
+ if (!contextValue) {
10
+ throw new Error(
11
+ "[react-native-stylex]: Please make sure that you wrapped your component with <ThemeProvider/>."
12
+ );
13
+ }
14
+
15
+ return contextValue as Theme;
16
+ };
@@ -0,0 +1,35 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, {
3
+ ComponentProps,
4
+ ComponentType,
5
+ forwardRef,
6
+ Ref,
7
+ ElementRef
8
+ } from "react";
9
+
10
+ interface InjectedStyledProps<Styles> {
11
+ styles: Styles;
12
+ }
13
+
14
+ export type InferInjectedStyledProps<
15
+ Fn extends (...args: any) => any
16
+ > = InjectedStyledProps<ReturnType<Fn>>;
17
+
18
+ export function withStyles<Styles>(useStyles: () => Styles) {
19
+ function WithStyles<TComponent extends ComponentType<any>>(
20
+ Component: TComponent
21
+ ) {
22
+ const renderComponent = (
23
+ props: Omit<ComponentProps<TComponent>, "styles">,
24
+ ref: Ref<ElementRef<TComponent>>
25
+ ) => {
26
+ const styles = useStyles();
27
+ // @ts-expect-error: 'ref' as never
28
+ return <Component {...props} ref={ref} styles={styles} />;
29
+ };
30
+
31
+ return forwardRef(renderComponent);
32
+ }
33
+
34
+ return WithStyles;
35
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "module": "ESNext",
4
+ "target": "ESNext",
5
+ "lib": ["ESNext"],
6
+ "skipLibCheck": true,
7
+ "declaration": true,
8
+ "rootDir": "./src",
9
+ "jsx": "react-native",
10
+ "strict": true,
11
+ "esModuleInterop": true,
12
+ "isolatedModules": true,
13
+ "noImplicitAny": true,
14
+ "strictNullChecks": true,
15
+ "strictFunctionTypes": true,
16
+ "strictBindCallApply": true,
17
+ "strictPropertyInitialization": true,
18
+ "noImplicitThis": true,
19
+ "alwaysStrict": true,
20
+ "noUnusedLocals": false,
21
+ "noUnusedParameters": true,
22
+ "noImplicitReturns": true,
23
+ "noFallthroughCasesInSwitch": true,
24
+ "noUncheckedIndexedAccess": true,
25
+ "forceConsistentCasingInFileNames": true,
26
+ "moduleResolution": "node",
27
+ "outDir": "./lib"
28
+ },
29
+ "include": ["./src"]
30
+ }