cpk-ui 0.0.1
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 +27 -0
- package/components/modals/AlertDialog/AlertDialog.js +80 -0
- package/components/modals/AlertDialog/AlertDialog.stories.tsx +80 -0
- package/components/modals/AlertDialog/AlertDialog.tsx +194 -0
- package/components/modals/Snackbar/Snackbar.js +94 -0
- package/components/modals/Snackbar/Snackbar.stories.tsx +98 -0
- package/components/modals/Snackbar/Snackbar.tsx +174 -0
- package/components/modals/Snackbar/const.js +5 -0
- package/components/modals/Snackbar/const.ts +4 -0
- package/components/uis/Accordion/Accordion.js +11 -0
- package/components/uis/Accordion/Accordion.stories.tsx +38 -0
- package/components/uis/Accordion/Accordion.test.tsx +128 -0
- package/components/uis/Accordion/Accordion.tsx +58 -0
- package/components/uis/Accordion/AccordionItem.js +102 -0
- package/components/uis/Accordion/AccordionItem.tsx +213 -0
- package/components/uis/Button/Button.js +161 -0
- package/components/uis/Button/Button.stories.tsx +81 -0
- package/components/uis/Button/Button.test.tsx +560 -0
- package/components/uis/Button/Button.tsx +335 -0
- package/components/uis/Checkbox/Checkbox.js +70 -0
- package/components/uis/Checkbox/Checkbox.stories.tsx +46 -0
- package/components/uis/Checkbox/Checkbox.test.tsx +139 -0
- package/components/uis/Checkbox/Checkbox.tsx +150 -0
- package/components/uis/Icon/Icon.js +3780 -0
- package/components/uis/Icon/Icon.stories.tsx +45 -0
- package/components/uis/Icon/Icon.test.tsx +19 -0
- package/components/uis/Icon/Icon.tsx +3800 -0
- package/components/uis/Icon/Pretendard-Bold.otf +0 -0
- package/components/uis/Icon/Pretendard-Regular.otf +0 -0
- package/components/uis/Icon/Pretendard-Thin.otf +0 -0
- package/components/uis/Icon/cpk.ttf +0 -0
- package/components/uis/Icon/selection.json +1 -0
- package/components/uis/IconButton/IconButton.js +120 -0
- package/components/uis/IconButton/IconButton.test.tsx +165 -0
- package/components/uis/IconButton/IconButton.tsx +252 -0
- package/components/uis/LoadingIndicator/LoadingIndicator.js +24 -0
- package/components/uis/LoadingIndicator/LoadingIndicator.tsx +79 -0
- package/components/uis/Rating/Rating.js +53 -0
- package/components/uis/Rating/Rating.test.tsx +72 -0
- package/components/uis/Rating/Rating.tsx +155 -0
- package/components/uis/StatusbarBrightness/StatusBarBrightness.js +13 -0
- package/components/uis/StatusbarBrightness/StatusBarBrightness.test.tsx +41 -0
- package/components/uis/StatusbarBrightness/StatusBarBrightness.tsx +17 -0
- package/components/uis/Styled/StyledComponents.js +130 -0
- package/components/uis/Styled/StyledComponents.tsx +200 -0
- package/components/uis/SwitchToggle/SwitchToggle.js +126 -0
- package/components/uis/SwitchToggle/SwitchToggle.test.tsx +70 -0
- package/components/uis/SwitchToggle/SwitchToggle.tsx +224 -0
- package/components/uis/Typography/Typography.js +90 -0
- package/components/uis/Typography/Typography.test.tsx +58 -0
- package/components/uis/Typography/Typography.tsx +132 -0
- package/hooks/useDebouncedColorScheme.js +21 -0
- package/hooks/useDebouncedColorScheme.tsx +30 -0
- package/index.js +16 -0
- package/index.tsx +18 -0
- package/package.json +35 -0
- package/providers/ThemeProvider.js +106 -0
- package/providers/ThemeProvider.tsx +180 -0
- package/providers/index.js +62 -0
- package/providers/index.tsx +125 -0
- package/react-native.config.cjs +5 -0
- package/utils/colors.js +124 -0
- package/utils/colors.ts +127 -0
- package/utils/createCtx.js +15 -0
- package/utils/createCtx.tsx +26 -0
- package/utils/guards.js +44 -0
- package/utils/guards.ts +93 -0
- package/utils/theme.js +5 -0
- package/utils/theme.ts +33 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { useColorScheme } from "react-native";
|
|
3
|
+
function useDebounce(value, delay) {
|
|
4
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
|
|
7
|
+
return () => {
|
|
8
|
+
clearTimeout(timer);
|
|
9
|
+
};
|
|
10
|
+
}, [value, delay]);
|
|
11
|
+
return debouncedValue;
|
|
12
|
+
}
|
|
13
|
+
/* ?
|
|
14
|
+
* Strangely enough, when useColorScheme() returns from the background state, it first returns a different color value and later returns the original color value.
|
|
15
|
+
* Due to this phenomenon, there's a momentary flickering effect on the screen.
|
|
16
|
+
* Therefore, to prevent this, we use useDebounce to delay the return of the color value until after a certain amount of time has passed.
|
|
17
|
+
*/
|
|
18
|
+
export function useDebouncedColorScheme(delay = 300) {
|
|
19
|
+
const colorScheme = useColorScheme();
|
|
20
|
+
return useDebounce(colorScheme, delay);
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import type { ColorSchemeName } from "react-native";
|
|
3
|
+
import { useColorScheme } from "react-native";
|
|
4
|
+
|
|
5
|
+
function useDebounce<T>(value: T, delay?: number): T {
|
|
6
|
+
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay || 500);
|
|
10
|
+
|
|
11
|
+
return () => {
|
|
12
|
+
clearTimeout(timer);
|
|
13
|
+
};
|
|
14
|
+
}, [value, delay]);
|
|
15
|
+
|
|
16
|
+
return debouncedValue;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* ?
|
|
20
|
+
* Strangely enough, when useColorScheme() returns from the background state, it first returns a different color value and later returns the original color value.
|
|
21
|
+
* Due to this phenomenon, there's a momentary flickering effect on the screen.
|
|
22
|
+
* Therefore, to prevent this, we use useDebounce to delay the return of the color value until after a certain amount of time has passed.
|
|
23
|
+
*/
|
|
24
|
+
export function useDebouncedColorScheme(
|
|
25
|
+
delay: number = 300
|
|
26
|
+
): "light" | "dark" | null | undefined {
|
|
27
|
+
const colorScheme = useColorScheme();
|
|
28
|
+
|
|
29
|
+
return useDebounce<ColorSchemeName>(colorScheme, delay);
|
|
30
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Modals
|
|
2
|
+
export * from './components/modals/AlertDialog/AlertDialog';
|
|
3
|
+
export * from './components/modals/Snackbar/Snackbar';
|
|
4
|
+
// Providers
|
|
5
|
+
export * from './providers';
|
|
6
|
+
// UIs
|
|
7
|
+
export * from './components/uis/Accordion/Accordion';
|
|
8
|
+
export * from './components/uis/Button/Button';
|
|
9
|
+
export * from './components/uis/Checkbox/Checkbox';
|
|
10
|
+
export * from './components/uis/Icon/Icon';
|
|
11
|
+
export * from './components/uis/IconButton/IconButton';
|
|
12
|
+
export * from './components/uis/LoadingIndicator/LoadingIndicator';
|
|
13
|
+
export * from './components/uis/Rating/Rating';
|
|
14
|
+
export * from './components/uis/StatusbarBrightness/StatusBarBrightness';
|
|
15
|
+
export * from './components/uis/SwitchToggle/SwitchToggle';
|
|
16
|
+
export * from './components/uis/Typography/Typography';
|
package/index.tsx
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Modals
|
|
2
|
+
export * from './components/modals/AlertDialog/AlertDialog';
|
|
3
|
+
export * from './components/modals/Snackbar/Snackbar';
|
|
4
|
+
|
|
5
|
+
// Providers
|
|
6
|
+
export * from './providers';
|
|
7
|
+
|
|
8
|
+
// UIs
|
|
9
|
+
export * from './components/uis/Accordion/Accordion';
|
|
10
|
+
export * from './components/uis/Button/Button';
|
|
11
|
+
export * from './components/uis/Checkbox/Checkbox';
|
|
12
|
+
export * from './components/uis/Icon/Icon';
|
|
13
|
+
export * from './components/uis/IconButton/IconButton';
|
|
14
|
+
export * from './components/uis/LoadingIndicator/LoadingIndicator';
|
|
15
|
+
export * from './components/uis/Rating/Rating';
|
|
16
|
+
export * from './components/uis/StatusbarBrightness/StatusBarBrightness';
|
|
17
|
+
export * from './components/uis/SwitchToggle/SwitchToggle';
|
|
18
|
+
export * from './components/uis/Typography/Typography';
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cpk-ui",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "index",
|
|
5
|
+
"react-native": "index",
|
|
6
|
+
"module": "index",
|
|
7
|
+
"source": "index",
|
|
8
|
+
"types": "index.d.ts",
|
|
9
|
+
"author": "hyochan",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"pack": "yarn pack",
|
|
13
|
+
"publish:next": "npm publish <package>.tgz --tag next"
|
|
14
|
+
},
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/crossplatformkorea/CPK-UI/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/crossplatformkorea/CPK-UI#readme",
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@emotion/native": ">=11.0.0",
|
|
21
|
+
"@emotion/react": ">=11.0.0",
|
|
22
|
+
"react": ">=16.9",
|
|
23
|
+
"react-native": ">=0.58",
|
|
24
|
+
"react-native-gesture-handler": "*",
|
|
25
|
+
"@expo/vector-icons": "*"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"hyochan-welcome": "^1.0.1",
|
|
29
|
+
"react-native-web-hooks": "^3.0.2",
|
|
30
|
+
"react-responsive": "^10.0.0"
|
|
31
|
+
},
|
|
32
|
+
"publishConfig": {
|
|
33
|
+
"access": "public"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "@expo/match-media";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import { useMediaQuery } from "react-responsive";
|
|
5
|
+
import { ThemeProvider as EmotionThemeProvider, withTheme, } from "@emotion/react";
|
|
6
|
+
import { dark, light } from "../utils/colors";
|
|
7
|
+
import { useDebouncedColorScheme } from "../hooks/useDebouncedColorScheme";
|
|
8
|
+
import createCtx from "../utils/createCtx";
|
|
9
|
+
const [useCtx, CpkProvider] = createCtx();
|
|
10
|
+
const genTheme = (type, themeParam) => {
|
|
11
|
+
const theme = type === "light" ? light : dark;
|
|
12
|
+
return {
|
|
13
|
+
...themeParam?.[type],
|
|
14
|
+
bg: {
|
|
15
|
+
...theme.bg,
|
|
16
|
+
...(themeParam?.[type]?.bg || {}),
|
|
17
|
+
},
|
|
18
|
+
role: {
|
|
19
|
+
...theme.role,
|
|
20
|
+
...(themeParam?.[type]?.role || {}),
|
|
21
|
+
},
|
|
22
|
+
text: {
|
|
23
|
+
...theme.text,
|
|
24
|
+
...(themeParam?.[type]?.text || {}),
|
|
25
|
+
},
|
|
26
|
+
button: {
|
|
27
|
+
...theme.button,
|
|
28
|
+
primary: {
|
|
29
|
+
...theme.button.primary,
|
|
30
|
+
...(themeParam?.[type]?.button?.primary || {}),
|
|
31
|
+
},
|
|
32
|
+
secondary: {
|
|
33
|
+
...theme.button.secondary,
|
|
34
|
+
...(themeParam?.[type]?.button?.secondary || {}),
|
|
35
|
+
},
|
|
36
|
+
success: {
|
|
37
|
+
...theme.button.success,
|
|
38
|
+
...(themeParam?.[type]?.button?.success || {}),
|
|
39
|
+
},
|
|
40
|
+
warning: {
|
|
41
|
+
...theme.button.warning,
|
|
42
|
+
...(themeParam?.[type]?.button?.warning || {}),
|
|
43
|
+
},
|
|
44
|
+
danger: {
|
|
45
|
+
...theme.button.danger,
|
|
46
|
+
...(themeParam?.[type]?.button?.danger || {}),
|
|
47
|
+
},
|
|
48
|
+
info: {
|
|
49
|
+
...theme.button.info,
|
|
50
|
+
...(themeParam?.[type]?.button?.info || {}),
|
|
51
|
+
},
|
|
52
|
+
light: {
|
|
53
|
+
...theme.button.light,
|
|
54
|
+
...(themeParam?.[type]?.button?.light || {}),
|
|
55
|
+
},
|
|
56
|
+
disabled: {
|
|
57
|
+
...theme.button.disabled,
|
|
58
|
+
...(themeParam?.[type]?.button?.disabled || {}),
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export function ThemeProvider({ children, initialThemeType, customTheme = {}, responsiveDesignMode = "mobile-first", }) {
|
|
64
|
+
const isPortrait = useMediaQuery({ orientation: "portrait" });
|
|
65
|
+
const isMobile = useMediaQuery(responsiveDesignMode === "mobile-first"
|
|
66
|
+
? { minWidth: 0 }
|
|
67
|
+
: { minWidth: 0, maxWidth: 767 });
|
|
68
|
+
const isTablet = useMediaQuery(responsiveDesignMode === "mobile-first"
|
|
69
|
+
? { minWidth: 767 }
|
|
70
|
+
: { minWidth: 768, maxWidth: 992 });
|
|
71
|
+
const isDesktop = useMediaQuery(responsiveDesignMode === "mobile-first"
|
|
72
|
+
? { minWidth: 992 }
|
|
73
|
+
: { minWidth: 0 });
|
|
74
|
+
const colorScheme = useDebouncedColorScheme();
|
|
75
|
+
const [themeType, setThemeType] = useState(initialThemeType ?? colorScheme);
|
|
76
|
+
useEffect(() => {
|
|
77
|
+
if (!initialThemeType) {
|
|
78
|
+
setThemeType(colorScheme);
|
|
79
|
+
}
|
|
80
|
+
}, [colorScheme, initialThemeType]);
|
|
81
|
+
const changeThemeType = (themeTypeProp) => {
|
|
82
|
+
if (!themeTypeProp) {
|
|
83
|
+
setThemeType(themeType === "light" ? "dark" : "light");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
setThemeType(themeTypeProp);
|
|
87
|
+
};
|
|
88
|
+
const theme = {
|
|
89
|
+
light: genTheme("light", customTheme),
|
|
90
|
+
dark: genTheme("dark", customTheme),
|
|
91
|
+
}[themeType || "light"];
|
|
92
|
+
const media = {
|
|
93
|
+
isPortrait,
|
|
94
|
+
isMobile,
|
|
95
|
+
isTablet,
|
|
96
|
+
isDesktop,
|
|
97
|
+
};
|
|
98
|
+
return (_jsx(CpkProvider, { value: {
|
|
99
|
+
media,
|
|
100
|
+
themeType,
|
|
101
|
+
changeThemeType,
|
|
102
|
+
// @ts-ignore
|
|
103
|
+
theme,
|
|
104
|
+
}, children: _jsx(EmotionThemeProvider, { theme: { ...theme, ...media }, children: children }) }));
|
|
105
|
+
}
|
|
106
|
+
export { useCtx as useTheme, withTheme };
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import "@expo/match-media";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import type { ColorSchemeName } from "react-native";
|
|
5
|
+
import { useMediaQuery } from "react-responsive";
|
|
6
|
+
import type { Theme } from "@emotion/react";
|
|
7
|
+
import {
|
|
8
|
+
ThemeProvider as EmotionThemeProvider,
|
|
9
|
+
withTheme,
|
|
10
|
+
} from "@emotion/react";
|
|
11
|
+
|
|
12
|
+
import type { CpkTheme, ThemeParam } from "../utils/theme";
|
|
13
|
+
import { dark, light } from "../utils/colors";
|
|
14
|
+
import { useDebouncedColorScheme } from "../hooks/useDebouncedColorScheme";
|
|
15
|
+
import createCtx from "../utils/createCtx";
|
|
16
|
+
|
|
17
|
+
type ResponsiveDesignMode = "mobile-first" | "desktop-first";
|
|
18
|
+
export type ThemeType = "light" | "dark";
|
|
19
|
+
|
|
20
|
+
export type ThemeContext = {
|
|
21
|
+
themeType: ColorSchemeName;
|
|
22
|
+
media: {
|
|
23
|
+
isPortrait: boolean;
|
|
24
|
+
isMobile: boolean;
|
|
25
|
+
isTablet: boolean;
|
|
26
|
+
isDesktop: boolean;
|
|
27
|
+
};
|
|
28
|
+
theme: Theme & CpkTheme;
|
|
29
|
+
changeThemeType: (themeType?: ColorSchemeName) => void;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const [useCtx, CpkProvider] = createCtx<ThemeContext>();
|
|
33
|
+
|
|
34
|
+
export type ThemeProps = {
|
|
35
|
+
children?: JSX.Element;
|
|
36
|
+
initialThemeType?: ThemeType;
|
|
37
|
+
customTheme?: ThemeParam;
|
|
38
|
+
/*
|
|
39
|
+
@description
|
|
40
|
+
default: mobile-first
|
|
41
|
+
- mobile-first: mobile first responsive design mode
|
|
42
|
+
- desktop-first: desktop first responsive design mode
|
|
43
|
+
*/
|
|
44
|
+
responsiveDesignMode?: ResponsiveDesignMode;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const genTheme = (type: ThemeType, themeParam: ThemeParam): any => {
|
|
48
|
+
const theme = type === "light" ? light : dark;
|
|
49
|
+
|
|
50
|
+
return {
|
|
51
|
+
...themeParam?.[type],
|
|
52
|
+
bg: {
|
|
53
|
+
...theme.bg,
|
|
54
|
+
...(themeParam?.[type]?.bg || {}),
|
|
55
|
+
},
|
|
56
|
+
role: {
|
|
57
|
+
...theme.role,
|
|
58
|
+
...(themeParam?.[type]?.role || {}),
|
|
59
|
+
},
|
|
60
|
+
text: {
|
|
61
|
+
...theme.text,
|
|
62
|
+
...(themeParam?.[type]?.text || {}),
|
|
63
|
+
},
|
|
64
|
+
button: {
|
|
65
|
+
...theme.button,
|
|
66
|
+
primary: {
|
|
67
|
+
...theme.button.primary,
|
|
68
|
+
...(themeParam?.[type]?.button?.primary || {}),
|
|
69
|
+
},
|
|
70
|
+
secondary: {
|
|
71
|
+
...theme.button.secondary,
|
|
72
|
+
...(themeParam?.[type]?.button?.secondary || {}),
|
|
73
|
+
},
|
|
74
|
+
success: {
|
|
75
|
+
...theme.button.success,
|
|
76
|
+
...(themeParam?.[type]?.button?.success || {}),
|
|
77
|
+
},
|
|
78
|
+
warning: {
|
|
79
|
+
...theme.button.warning,
|
|
80
|
+
...(themeParam?.[type]?.button?.warning || {}),
|
|
81
|
+
},
|
|
82
|
+
danger: {
|
|
83
|
+
...theme.button.danger,
|
|
84
|
+
...(themeParam?.[type]?.button?.danger || {}),
|
|
85
|
+
},
|
|
86
|
+
info: {
|
|
87
|
+
...theme.button.info,
|
|
88
|
+
...(themeParam?.[type]?.button?.info || {}),
|
|
89
|
+
},
|
|
90
|
+
light: {
|
|
91
|
+
...theme.button.light,
|
|
92
|
+
...(themeParam?.[type]?.button?.light || {}),
|
|
93
|
+
},
|
|
94
|
+
disabled: {
|
|
95
|
+
...theme.button.disabled,
|
|
96
|
+
...(themeParam?.[type]?.button?.disabled || {}),
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export function ThemeProvider({
|
|
103
|
+
children,
|
|
104
|
+
initialThemeType,
|
|
105
|
+
customTheme = {},
|
|
106
|
+
responsiveDesignMode = "mobile-first",
|
|
107
|
+
}: ThemeProps): JSX.Element {
|
|
108
|
+
const isPortrait = useMediaQuery({ orientation: "portrait" });
|
|
109
|
+
|
|
110
|
+
const isMobile = useMediaQuery(
|
|
111
|
+
responsiveDesignMode === "mobile-first"
|
|
112
|
+
? { minWidth: 0 }
|
|
113
|
+
: { minWidth: 0, maxWidth: 767 }
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const isTablet = useMediaQuery(
|
|
117
|
+
responsiveDesignMode === "mobile-first"
|
|
118
|
+
? { minWidth: 767 }
|
|
119
|
+
: { minWidth: 768, maxWidth: 992 }
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const isDesktop = useMediaQuery(
|
|
123
|
+
responsiveDesignMode === "mobile-first"
|
|
124
|
+
? { minWidth: 992 }
|
|
125
|
+
: { minWidth: 0 }
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const colorScheme = useDebouncedColorScheme();
|
|
129
|
+
const [themeType, setThemeType] = useState(initialThemeType ?? colorScheme);
|
|
130
|
+
|
|
131
|
+
useEffect(() => {
|
|
132
|
+
if (!initialThemeType) {
|
|
133
|
+
setThemeType(colorScheme);
|
|
134
|
+
}
|
|
135
|
+
}, [colorScheme, initialThemeType]);
|
|
136
|
+
|
|
137
|
+
const changeThemeType = (themeTypeProp?: ColorSchemeName): void => {
|
|
138
|
+
if (!themeTypeProp) {
|
|
139
|
+
setThemeType(themeType === "light" ? "dark" : "light");
|
|
140
|
+
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
setThemeType(themeTypeProp);
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const theme: Omit<
|
|
148
|
+
CpkTheme,
|
|
149
|
+
"isPortrait" | "isMobile" | "isTablet" | "isDesktop"
|
|
150
|
+
> = {
|
|
151
|
+
light: genTheme("light", customTheme),
|
|
152
|
+
dark: genTheme("dark", customTheme),
|
|
153
|
+
}[themeType || "light"];
|
|
154
|
+
|
|
155
|
+
const media = {
|
|
156
|
+
isPortrait,
|
|
157
|
+
isMobile,
|
|
158
|
+
isTablet,
|
|
159
|
+
isDesktop,
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
return (
|
|
163
|
+
<CpkProvider
|
|
164
|
+
value={{
|
|
165
|
+
media,
|
|
166
|
+
themeType,
|
|
167
|
+
changeThemeType,
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
theme,
|
|
170
|
+
}}
|
|
171
|
+
>
|
|
172
|
+
{/* @ts-ignore */}
|
|
173
|
+
<EmotionThemeProvider theme={{ ...theme, ...media }}>
|
|
174
|
+
{children}
|
|
175
|
+
</EmotionThemeProvider>
|
|
176
|
+
</CpkProvider>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export { useCtx as useTheme, withTheme };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef } from 'react';
|
|
3
|
+
import { View } from 'react-native';
|
|
4
|
+
import { css } from '@emotion/native';
|
|
5
|
+
import { useFonts } from 'expo-font';
|
|
6
|
+
import createCtx from '../utils/createCtx';
|
|
7
|
+
import { ThemeProvider, useTheme, } from './ThemeProvider';
|
|
8
|
+
import Snackbar from '../components/modals/Snackbar/Snackbar';
|
|
9
|
+
import AlertDialog from '../components/modals/AlertDialog/AlertDialog';
|
|
10
|
+
import { LoadingIndicator } from '../components/uis/LoadingIndicator/LoadingIndicator';
|
|
11
|
+
const [useCtx, Provider] = createCtx();
|
|
12
|
+
function AppProvider({ children }) {
|
|
13
|
+
const [assetLoaded] = useFonts({
|
|
14
|
+
cpk: require('../components/uis/Icon/cpk.ttf'),
|
|
15
|
+
'Pretendard-Bold': require('../components/uis/Icon/Pretendard-Bold.otf'),
|
|
16
|
+
Pretendard: require('../components/uis/Icon/Pretendard-Regular.otf'),
|
|
17
|
+
'Pretendard-Thin': require('../components/uis/Icon/Pretendard-Thin.otf'),
|
|
18
|
+
});
|
|
19
|
+
const themeContext = useTheme();
|
|
20
|
+
const snackbar = useRef();
|
|
21
|
+
const alertDialog = useRef();
|
|
22
|
+
/**
|
|
23
|
+
** Snackbar
|
|
24
|
+
*/
|
|
25
|
+
const snackbarContext = {
|
|
26
|
+
open: (snackbarOption) => {
|
|
27
|
+
snackbar.current && snackbar.current.open(snackbarOption);
|
|
28
|
+
},
|
|
29
|
+
close: () => {
|
|
30
|
+
snackbar.current && snackbar.current.close();
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
** AlertDialog
|
|
35
|
+
*/
|
|
36
|
+
const alertDialogContext = {
|
|
37
|
+
open: (alertDialogOptions) => {
|
|
38
|
+
alertDialog.current && alertDialog.current.open(alertDialogOptions);
|
|
39
|
+
},
|
|
40
|
+
close: () => {
|
|
41
|
+
alertDialog.current && alertDialog.current.close();
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
return (_jsx(View, { style: css `
|
|
45
|
+
flex: 1;
|
|
46
|
+
`, children: _jsx(Provider, { value: {
|
|
47
|
+
...themeContext,
|
|
48
|
+
assetLoaded,
|
|
49
|
+
snackbar: snackbarContext,
|
|
50
|
+
alertDialog: alertDialogContext,
|
|
51
|
+
}, children: !assetLoaded ? (_jsx(LoadingIndicator, { style: css `
|
|
52
|
+
align-self: stretch;
|
|
53
|
+
flex: 1;
|
|
54
|
+
justify-content: center;
|
|
55
|
+
background-color: ${themeContext.theme.bg.basic};
|
|
56
|
+
` })) : (_jsxs(_Fragment, { children: [children, _jsx(Snackbar, { ref: snackbar }), _jsx(AlertDialog, { ref: alertDialog })] })) }) }));
|
|
57
|
+
}
|
|
58
|
+
function CpkWithThemeProvider(props) {
|
|
59
|
+
const { themeConfig } = props;
|
|
60
|
+
return (_jsx(ThemeProvider, { ...themeConfig, children: _jsx(AppProvider, { ...props }) }));
|
|
61
|
+
}
|
|
62
|
+
export { useCtx as useCPK, CpkWithThemeProvider as CpkProvider };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type {MutableRefObject} from 'react';
|
|
2
|
+
import {useRef} from 'react';
|
|
3
|
+
import {View} from 'react-native';
|
|
4
|
+
import {css} from '@emotion/native';
|
|
5
|
+
import {useFonts} from 'expo-font';
|
|
6
|
+
|
|
7
|
+
import createCtx from '../utils/createCtx';
|
|
8
|
+
import {
|
|
9
|
+
ThemeContext,
|
|
10
|
+
ThemeProps,
|
|
11
|
+
ThemeProvider,
|
|
12
|
+
useTheme,
|
|
13
|
+
} from './ThemeProvider';
|
|
14
|
+
import Snackbar, {
|
|
15
|
+
SnackbarContext,
|
|
16
|
+
SnackbarOptions,
|
|
17
|
+
} from '../components/modals/Snackbar/Snackbar';
|
|
18
|
+
import AlertDialog, {
|
|
19
|
+
AlertDialogContext,
|
|
20
|
+
} from '../components/modals/AlertDialog/AlertDialog';
|
|
21
|
+
import {LoadingIndicator} from '../components/uis/LoadingIndicator/LoadingIndicator';
|
|
22
|
+
|
|
23
|
+
export type ThemeType = ThemeContext['themeType'];
|
|
24
|
+
export type DoobooTheme = ThemeContext['theme'];
|
|
25
|
+
|
|
26
|
+
export type CpkContext = {
|
|
27
|
+
assetLoaded: boolean;
|
|
28
|
+
snackbar: SnackbarContext;
|
|
29
|
+
alertDialog: AlertDialogContext;
|
|
30
|
+
} & ThemeContext;
|
|
31
|
+
|
|
32
|
+
const [useCtx, Provider] = createCtx<CpkContext>();
|
|
33
|
+
|
|
34
|
+
function AppProvider({children}: {children: JSX.Element}): JSX.Element {
|
|
35
|
+
const [assetLoaded] = useFonts({
|
|
36
|
+
cpk: require('../components/uis/Icon/cpk.ttf'),
|
|
37
|
+
'Pretendard-Bold': require('../components/uis/Icon/Pretendard-Bold.otf'),
|
|
38
|
+
Pretendard: require('../components/uis/Icon/Pretendard-Regular.otf'),
|
|
39
|
+
'Pretendard-Thin': require('../components/uis/Icon/Pretendard-Thin.otf'),
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const themeContext = useTheme();
|
|
43
|
+
|
|
44
|
+
const snackbar =
|
|
45
|
+
useRef<SnackbarContext>() as MutableRefObject<SnackbarContext>;
|
|
46
|
+
|
|
47
|
+
const alertDialog =
|
|
48
|
+
useRef<AlertDialogContext>() as MutableRefObject<AlertDialogContext>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
** Snackbar
|
|
52
|
+
*/
|
|
53
|
+
const snackbarContext: SnackbarContext = {
|
|
54
|
+
open: (snackbarOption): void => {
|
|
55
|
+
snackbar.current && snackbar.current.open(snackbarOption);
|
|
56
|
+
},
|
|
57
|
+
close: (): void => {
|
|
58
|
+
snackbar.current && snackbar.current.close();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
** AlertDialog
|
|
64
|
+
*/
|
|
65
|
+
const alertDialogContext: AlertDialogContext = {
|
|
66
|
+
open: (alertDialogOptions): void => {
|
|
67
|
+
alertDialog.current && alertDialog.current.open(alertDialogOptions);
|
|
68
|
+
},
|
|
69
|
+
close: (): void => {
|
|
70
|
+
alertDialog.current && alertDialog.current.close();
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<View
|
|
76
|
+
style={css`
|
|
77
|
+
flex: 1;
|
|
78
|
+
`}
|
|
79
|
+
>
|
|
80
|
+
<Provider
|
|
81
|
+
value={{
|
|
82
|
+
...themeContext,
|
|
83
|
+
assetLoaded,
|
|
84
|
+
snackbar: snackbarContext,
|
|
85
|
+
alertDialog: alertDialogContext,
|
|
86
|
+
}}
|
|
87
|
+
>
|
|
88
|
+
{!assetLoaded ? (
|
|
89
|
+
<LoadingIndicator
|
|
90
|
+
style={css`
|
|
91
|
+
align-self: stretch;
|
|
92
|
+
flex: 1;
|
|
93
|
+
justify-content: center;
|
|
94
|
+
background-color: ${themeContext.theme.bg.basic};
|
|
95
|
+
`}
|
|
96
|
+
/>
|
|
97
|
+
) : (
|
|
98
|
+
<>
|
|
99
|
+
{children}
|
|
100
|
+
<Snackbar ref={snackbar} />
|
|
101
|
+
<AlertDialog ref={alertDialog} />
|
|
102
|
+
</>
|
|
103
|
+
)}
|
|
104
|
+
</Provider>
|
|
105
|
+
</View>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type CpkProviderProps = {
|
|
110
|
+
themeConfig?: Omit<ThemeProps, 'children'>;
|
|
111
|
+
snackbarConfig?: SnackbarOptions;
|
|
112
|
+
children: JSX.Element;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
function CpkWithThemeProvider(props: CpkProviderProps): JSX.Element {
|
|
116
|
+
const {themeConfig} = props;
|
|
117
|
+
|
|
118
|
+
return (
|
|
119
|
+
<ThemeProvider {...themeConfig}>
|
|
120
|
+
<AppProvider {...props} />
|
|
121
|
+
</ThemeProvider>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export {useCtx as useCPK, CpkWithThemeProvider as CpkProvider};
|