@0610studio/zs-ui 0.1.2 → 0.1.4

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.
@@ -4,6 +4,7 @@ import { ElevationStyles } from '../theme/elevation';
4
4
  export interface ThemeProviderProps {
5
5
  themeFonts?: ThemeFonts;
6
6
  children: React.ReactNode;
7
+ isDarkModeEnabled?: boolean;
7
8
  }
8
9
  export interface ThemeProps {
9
10
  palette: Palette;
@@ -1 +1 @@
1
- {"version":3,"file":"useThemeProvider.d.ts","sourceRoot":"","sources":["../../src/model/useThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+E,MAAM,OAAO,CAAC;AAKpG,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,uBAAuB,CAAC;IACpC,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,OAAQ,SAAQ,KAAK;IACpC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,wBAAwB,EAAE,OAAO,CAAC;IAClC,uBAAuB,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAID,eAAO,MAAM,QAAQ,kBAMpB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAkFtD,CAAA"}
1
+ {"version":3,"file":"useThemeProvider.d.ts","sourceRoot":"","sources":["../../src/model/useThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+E,MAAM,OAAO,CAAC;AAKpG,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAE5E,OAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,uBAAuB,CAAC;IACpC,SAAS,EAAE,eAAe,CAAC;CAC5B;AAED,MAAM,WAAW,OAAQ,SAAQ,KAAK;IACpC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,wBAAwB,EAAE,OAAO,CAAC;IAClC,uBAAuB,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAID,eAAO,MAAM,QAAQ,kBAMpB,CAAA;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsFtD,CAAA"}
@@ -13,26 +13,31 @@ export const useTheme = () => {
13
13
  }
14
14
  return context;
15
15
  };
16
- export const ThemeProvider = ({ themeFonts, children }) => {
16
+ export const ThemeProvider = ({ themeFonts, children, isDarkModeEnabled = true }) => {
17
17
  const systemColorScheme = useColorScheme(); // 시스템 다크 모드 감지
18
- const [isUsingSystemColorScheme, setUseSystemColorScheme] = useState(true);
19
- const [mode, setMode] = useState(systemColorScheme === 'dark' ? 'dark' : 'light');
18
+ const [isUsingSystemColorScheme, setUseSystemColorScheme] = useState(isDarkModeEnabled ? true : false);
19
+ const [mode, setMode] = useState(isDarkModeEnabled ? (systemColorScheme === 'dark' ? 'dark' : 'light') : 'light');
20
20
  // AsyncStorage에서 시스템 모드 사용 설정 값 로드
21
21
  useEffect(() => {
22
22
  const loadSettings = async () => {
23
23
  let isMounted = true;
24
24
  try {
25
- const storedUseSystemColorScheme = await AsyncStorage.getItem('useSystemColorScheme');
26
- const storedMode = await AsyncStorage.getItem('themeMode');
27
25
  if (isMounted) {
28
- if (storedUseSystemColorScheme !== null) {
29
- setUseSystemColorScheme(storedUseSystemColorScheme === 'true');
30
- }
31
- if (storedMode) {
32
- setMode(storedMode === 'dark' ? 'dark' : 'light');
26
+ if (isDarkModeEnabled) {
27
+ const storedUseSystemColorScheme = await AsyncStorage.getItem('useSystemColorScheme');
28
+ const storedMode = await AsyncStorage.getItem('themeMode');
29
+ if (storedUseSystemColorScheme !== null) {
30
+ setUseSystemColorScheme(storedUseSystemColorScheme === 'true');
31
+ }
32
+ if (storedMode) {
33
+ setMode(storedMode === 'dark' ? 'dark' : 'light');
34
+ }
35
+ else {
36
+ setMode(systemColorScheme === 'dark' ? 'dark' : 'light');
37
+ }
33
38
  }
34
39
  else {
35
- setMode(systemColorScheme === 'dark' ? 'dark' : 'light');
40
+ setMode('light');
36
41
  }
37
42
  }
38
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useThemeProvider.js","sourceRoot":"","sources":["../../src/model/useThemeProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpG,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,YAAY,MAAM,2CAA2C,CAAC;AACrE,OAAO,KAAK,aAAa,MAAM,qBAAqB,CAAC;AACrD,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAEvC,OAAO,UAAU,MAAM,qBAAqB,CAAC;AAC7C,OAAO,SAA8B,MAAM,oBAAoB,CAAC;AAoBhE,MAAM,YAAY,GAAG,aAAa,CAAoB,IAAI,CAAC,CAAC;AAE5D,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,EAAE;IAC3B,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IACzC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;IACtF,MAAM,iBAAiB,GAAG,cAAc,EAAE,CAAC,CAAC,eAAe;IAC3D,MAAM,CAAC,wBAAwB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC3E,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAmB,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAEpG,mCAAmC;IACnC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;YAC9B,IAAI,SAAS,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,0BAA0B,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;gBACtF,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;gBAE3D,IAAI,SAAS,EAAE,CAAC;oBACd,IAAI,0BAA0B,KAAK,IAAI,EAAE,CAAC;wBACxC,uBAAuB,CAAC,0BAA0B,KAAK,MAAM,CAAC,CAAC;oBACjE,CAAC;oBACD,IAAI,UAAU,EAAE,CAAC;wBACf,OAAO,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;oBACpD,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;oBAC3D,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC;YAED,OAAO,GAAG,EAAE;gBACV,SAAS,GAAG,KAAK,CAAC;YACpB,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,YAAY,EAAE,CAAC;IACjB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,yBAAyB;IACzB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,wBAAwB,EAAE,CAAC;YAC7B,OAAO,CAAC,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAE/B,sBAAsB;IACtB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9B,aAAa,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACxC,aAAa,CAAC,uBAAuB,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,WAAW;IACX,MAAM,WAAW,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QACzC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB;QAChD,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YACnB,MAAM,OAAO,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;YACxD,YAAY,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,aAAa;YACzD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,qBAAqB;IACrB,MAAM,6BAA6B,GAAG,WAAW,CAAC,KAAK,EAAE,SAAkB,EAAE,EAAE;QAC7E,uBAAuB,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,YAAY,CAAC,OAAO,CAAC,sBAAsB,EAAE,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3E,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAChC,OAAO,EAAE;YACP,wBAAwB;YACxB,uBAAuB,EAAE,6BAA6B;YACtD,WAAW;YACX,GAAG,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,oBAAoB;SAC3C;QACD,UAAU,EAAE,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;QACtC,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;KACxC,CAAC,EAAE,CAAC,IAAI,EAAE,wBAAwB,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAE9D,OAAO,CACL,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,CACvC;MAAA,CAAC,QAAQ,CACX;IAAA,EAAE,YAAY,CAAC,QAAQ,CAAC,CACzB,CAAC;AACJ,CAAC,CAAA","sourcesContent":["import React, { createContext, useContext, useMemo, useState, useEffect, useCallback } from 'react';\nimport { Platform, useColorScheme } from 'react-native';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as NavigationBar from 'expo-navigation-bar';\nimport palette from '../theme/palette';\nimport { Theme, ThemeFonts, TypographyVariantsProps } from '../theme/types';\nimport typography from '../theme/typography';\nimport elevation, { ElevationStyles } from '../theme/elevation';\n\nexport interface ThemeProviderProps {\n themeFonts?: ThemeFonts;\n children: React.ReactNode;\n}\n\nexport interface ThemeProps {\n palette: Palette;\n typography: TypographyVariantsProps;\n elevation: ElevationStyles;\n}\n\nexport interface Palette extends Theme {\n mode: 'light' | 'dark';\n isUsingSystemColorScheme: boolean;\n setUseSystemColorScheme: (useSystem: boolean) => void;\n toggleTheme: () => void;\n}\n\nconst ThemeContext = createContext<ThemeProps | null>(null);\n\nexport const useTheme = () => {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({ themeFonts, children }) => {\n const systemColorScheme = useColorScheme(); // 시스템 다크 모드 감지\n const [isUsingSystemColorScheme, setUseSystemColorScheme] = useState(true);\n const [mode, setMode] = useState<'light' | 'dark'>(systemColorScheme === 'dark' ? 'dark' : 'light');\n\n // AsyncStorage에서 시스템 모드 사용 설정 값 로드\n useEffect(() => {\n const loadSettings = async () => {\n let isMounted = true;\n try {\n const storedUseSystemColorScheme = await AsyncStorage.getItem('useSystemColorScheme');\n const storedMode = await AsyncStorage.getItem('themeMode');\n\n if (isMounted) {\n if (storedUseSystemColorScheme !== null) {\n setUseSystemColorScheme(storedUseSystemColorScheme === 'true');\n }\n if (storedMode) {\n setMode(storedMode === 'dark' ? 'dark' : 'light');\n } else {\n setMode(systemColorScheme === 'dark' ? 'dark' : 'light');\n }\n }\n } catch (error) {\n console.error('Failed to load theme settings', error);\n }\n\n return () => {\n isMounted = false;\n };\n };\n\n loadSettings();\n }, []);\n\n // 시스템 다크 모드 변경에 따른 효과 적용\n useEffect(() => {\n if (isUsingSystemColorScheme) {\n setMode(systemColorScheme === 'dark' ? 'dark' : 'light');\n }\n }, [isUsingSystemColorScheme]);\n\n // 안드로이드 하단 제스쳐 영역 스타일\n useEffect(() => {\n if (Platform.OS === 'android') {\n NavigationBar.setButtonStyleAsync(mode);\n NavigationBar.setBackgroundColorAsync(palette({ mode }).background.base)\n }\n }, [mode])\n\n // 테마 토글 함수\n const toggleTheme = useCallback(async () => {\n setUseSystemColorScheme(false); // 사용자 지정 모드로 전환\n setMode((prevMode) => {\n const newMode = prevMode === 'light' ? 'dark' : 'light';\n AsyncStorage.setItem('themeMode', newMode); // 로컬스토리지에 저장\n return newMode;\n });\n }, []);\n\n // 시스템 모드 사용 설정 변경 함수\n const handleSetUseSystemColorScheme = useCallback(async (useSystem: boolean) => {\n setUseSystemColorScheme(useSystem);\n await AsyncStorage.setItem('useSystemColorScheme', useSystem.toString());\n }, []);\n\n const themeValue = useMemo(() => ({\n palette: {\n isUsingSystemColorScheme,\n setUseSystemColorScheme: handleSetUseSystemColorScheme,\n toggleTheme,\n ...palette({ mode }), // 선택된 모드에 따른 팔레트 적용\n },\n typography: typography({ themeFonts }),\n elevation: elevation(palette({ mode }))\n }), [mode, isUsingSystemColorScheme, typography, themeFonts]);\n\n return (\n <ThemeContext.Provider value={themeValue}>\n {children}\n </ThemeContext.Provider>\n );\n}\n"]}
1
+ {"version":3,"file":"useThemeProvider.js","sourceRoot":"","sources":["../../src/model/useThemeProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { createContext, useContext, useMemo, useState, useEffect, useCallback } from 'react';\nimport { Platform, useColorScheme } from 'react-native';\nimport AsyncStorage from '@react-native-async-storage/async-storage';\nimport * as NavigationBar from 'expo-navigation-bar';\nimport palette from '../theme/palette';\nimport { Theme, ThemeFonts, TypographyVariantsProps } from '../theme/types';\nimport typography from '../theme/typography';\nimport elevation, { ElevationStyles } from '../theme/elevation';\n\nexport interface ThemeProviderProps {\n themeFonts?: ThemeFonts;\n children: React.ReactNode;\n isDarkModeEnabled?: boolean;\n}\n\nexport interface ThemeProps {\n palette: Palette;\n typography: TypographyVariantsProps;\n elevation: ElevationStyles;\n}\n\nexport interface Palette extends Theme {\n mode: 'light' | 'dark';\n isUsingSystemColorScheme: boolean;\n setUseSystemColorScheme: (useSystem: boolean) => void;\n toggleTheme: () => void;\n}\n\nconst ThemeContext = createContext<ThemeProps | null>(null);\n\nexport const useTheme = () => {\n const context = useContext(ThemeContext);\n if (!context) {\n throw new Error('useTheme must be used within a ThemeProvider');\n }\n return context;\n}\n\nexport const ThemeProvider: React.FC<ThemeProviderProps> = ({ themeFonts, children, isDarkModeEnabled = true }) => {\n const systemColorScheme = useColorScheme(); // 시스템 다크 모드 감지\n const [isUsingSystemColorScheme, setUseSystemColorScheme] = useState(isDarkModeEnabled ? true : false);\n const [mode, setMode] = useState<'light' | 'dark'>(isDarkModeEnabled ? (systemColorScheme === 'dark' ? 'dark' : 'light') : 'light');\n\n // AsyncStorage에서 시스템 모드 사용 설정 값 로드\n useEffect(() => {\n const loadSettings = async () => {\n let isMounted = true;\n try {\n if (isMounted) {\n if (isDarkModeEnabled) {\n const storedUseSystemColorScheme = await AsyncStorage.getItem('useSystemColorScheme');\n const storedMode = await AsyncStorage.getItem('themeMode');\n\n if (storedUseSystemColorScheme !== null) {\n setUseSystemColorScheme(storedUseSystemColorScheme === 'true');\n }\n if (storedMode) {\n setMode(storedMode === 'dark' ? 'dark' : 'light');\n } else {\n setMode(systemColorScheme === 'dark' ? 'dark' : 'light');\n }\n } else {\n setMode('light');\n }\n }\n } catch (error) {\n console.error('Failed to load theme settings', error);\n }\n\n return () => {\n isMounted = false;\n };\n };\n\n loadSettings();\n }, []);\n\n // 시스템 다크 모드 변경에 따른 효과 적용\n useEffect(() => {\n if (isUsingSystemColorScheme) {\n setMode(systemColorScheme === 'dark' ? 'dark' : 'light');\n }\n }, [isUsingSystemColorScheme]);\n\n // 안드로이드 하단 제스쳐 영역 스타일\n useEffect(() => {\n if (Platform.OS === 'android') {\n NavigationBar.setButtonStyleAsync(mode);\n NavigationBar.setBackgroundColorAsync(palette({ mode }).background.base)\n }\n }, [mode])\n\n // 테마 토글 함수\n const toggleTheme = useCallback(async () => {\n setUseSystemColorScheme(false); // 사용자 지정 모드로 전환\n setMode((prevMode) => {\n const newMode = prevMode === 'light' ? 'dark' : 'light';\n AsyncStorage.setItem('themeMode', newMode); // 로컬스토리지에 저장\n return newMode;\n });\n }, []);\n\n // 시스템 모드 사용 설정 변경 함수\n const handleSetUseSystemColorScheme = useCallback(async (useSystem: boolean) => {\n setUseSystemColorScheme(useSystem);\n await AsyncStorage.setItem('useSystemColorScheme', useSystem.toString());\n }, []);\n\n const themeValue = useMemo(() => ({\n palette: {\n isUsingSystemColorScheme,\n setUseSystemColorScheme: handleSetUseSystemColorScheme,\n toggleTheme,\n ...palette({ mode }), // 선택된 모드에 따른 팔레트 적용\n },\n typography: typography({ themeFonts }),\n elevation: elevation(palette({ mode }))\n }), [mode, isUsingSystemColorScheme, typography, themeFonts]);\n\n return (\n <ThemeContext.Provider value={themeValue}>\n {children}\n </ThemeContext.Provider>\n );\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/ZSContainer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAgE,MAAM,OAAO,CAAC;AACvG,OAAO,EAAE,SAAS,EAA8E,UAAU,EAAqD,MAAM,cAAc,CAAC;AAMpL,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC;IAC5C,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC7C,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAC5C,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC;AAExC,QAAA,MAAM,WAAW;sBAlBG,MAAM;eACb,OAAO;qBACD,MAAM;eACZ,eAAe,GAAG,cAAc;YACnC,KAAK,CAAC,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;mBACnC,OAAO;mBACP,SAAS;sBACN,SAAS;mCACI,OAAO;uBACnB,KAAK,CAAC,SAAS;6BACT,MAAM;eACpB,SAAS,GAAG,QAAQ,GAAG,UAAU;wCACR,OAAO;gCACf,MAAM;oCA0HlC,CAAC;AAYH,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/ZSContainer/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAgE,MAAM,OAAO,CAAC;AACvG,OAAO,EAAE,SAAS,EAA8E,UAAU,EAAqD,MAAM,cAAc,CAAC;AAMpL,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,eAAe,GAAG,cAAc,CAAC;IAC5C,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;IACnD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC7C,iCAAiC,CAAC,EAAE,OAAO,CAAC;IAC5C,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC;AAExC,QAAA,MAAM,WAAW;sBAlBG,MAAM;eACb,OAAO;qBACD,MAAM;eACZ,eAAe,GAAG,cAAc;YACnC,KAAK,CAAC,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;mBACnC,OAAO;mBACP,SAAS;sBACN,SAAS;mCACI,OAAO;uBACnB,KAAK,CAAC,SAAS;6BACT,MAAM;eACpB,SAAS,GAAG,QAAQ,GAAG,UAAU;wCACR,OAAO;gCACf,MAAM;oCA8HlC,CAAC;AAYH,eAAe,WAAW,CAAC"}
@@ -4,7 +4,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
4
4
  import ViewAtom from '../atoms/ViewAtom';
5
5
  import ScrollViewAtom from '../atoms/ScrollViewAtom';
6
6
  import { useTheme } from '../../model/useThemeProvider';
7
- const ZSContainer = forwardRef(function ZSContainer({ backgroundColor, isLoader = false, statusBarColor, barStyle = 'dark-content', edges = ['top', 'bottom'], isScrollView = true, topComponent, bottomComponent, showsVerticalScrollIndicator = true, loadingComponent = <ActivityIndicator />, keyboardVerticalOffset, behavior, automaticallyAdjustKeyboardInsets = true, keyboardScrollExtraOffset = 100, ...props }, forwardedRef) {
7
+ const ZSContainer = forwardRef(function ZSContainer({ backgroundColor, isLoader = false, statusBarColor, barStyle = 'dark-content', edges = ['top', 'bottom'], isScrollView = true, topComponent, bottomComponent, showsVerticalScrollIndicator = true, loadingComponent = <ActivityIndicator />, keyboardVerticalOffset, behavior, automaticallyAdjustKeyboardInsets = true, keyboardScrollExtraOffset, ...props }, forwardedRef) {
8
8
  const { palette } = useTheme();
9
9
  const [isDelayed, setIsDelayed] = useState(true);
10
10
  const positionRef = useRef(0);
@@ -24,9 +24,12 @@ const ZSContainer = forwardRef(function ZSContainer({ backgroundColor, isLoader
24
24
  const keyboardHeight = e.endCoordinates.height;
25
25
  const safeAreaBottom = 0;
26
26
  const availableScreenHeight = screenHeight - keyboardHeight - safeAreaBottom;
27
- const delta = (lastTouchY?.current || 0) + keyboardScrollExtraOffset - availableScreenHeight;
27
+ // 현재 터치 위치와 스크롤 위치를 기반으로 새로운 스크롤 위치 계산
28
+ const currentScrollPosition = positionRef.current || 0;
29
+ const touchPosition = lastTouchY.current || 0;
30
+ const scrollOffset = touchPosition - availableScreenHeight + keyboardScrollExtraOffset;
28
31
  scrollViewRef.current.scrollTo({
29
- y: (positionRef.current ?? 0) + delta,
32
+ y: currentScrollPosition + scrollOffset,
30
33
  animated: true,
31
34
  });
32
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/ZSContainer/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactNode, useState, useEffect, useImperativeHandle, forwardRef, useRef } from 'react';\nimport { ViewProps, KeyboardAvoidingView, StatusBar, StyleSheet, Dimensions, ActivityIndicator, ScrollView, NativeSyntheticEvent, NativeScrollEvent, Keyboard } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport ViewAtom from '../atoms/ViewAtom';\nimport ScrollViewAtom from '../atoms/ScrollViewAtom';\nimport { useTheme } from '../../model/useThemeProvider';\n\nexport type ZSContainerProps = ViewProps & {\n backgroundColor?: string;\n isLoader?: boolean;\n statusBarColor?: string;\n barStyle?: 'light-content' | 'dark-content';\n edges?: Array<'top' | 'right' | 'bottom' | 'left'>;\n isScrollView?: boolean;\n topComponent?: ReactNode;\n bottomComponent?: ReactNode;\n showsVerticalScrollIndicator?: boolean;\n loadingComponent?: React.ReactNode;\n keyboardVerticalOffset?: number;\n behavior?: 'padding' | 'height' | 'position';\n automaticallyAdjustKeyboardInsets?: boolean;\n keyboardScrollExtraOffset?: number;\n};\n\nexport type ZSContainerRef = ScrollView;\n\nconst ZSContainer = forwardRef<ZSContainerRef, ZSContainerProps>(function ZSContainer(\n {\n backgroundColor,\n isLoader = false,\n statusBarColor,\n barStyle = 'dark-content',\n edges = ['top', 'bottom'],\n isScrollView = true,\n topComponent,\n bottomComponent,\n showsVerticalScrollIndicator = true,\n loadingComponent = <ActivityIndicator />,\n keyboardVerticalOffset,\n behavior,\n automaticallyAdjustKeyboardInsets = true,\n keyboardScrollExtraOffset = 100,\n ...props\n },\n forwardedRef\n) {\n const { palette } = useTheme();\n const [isDelayed, setIsDelayed] = useState(true);\n const positionRef = useRef<number | null>(0);\n const scrollViewRef = useRef<ScrollView>(null);\n const lastTouchY = useRef<number | null>(0);\n\n useImperativeHandle(forwardedRef, () => scrollViewRef.current as ScrollView, []);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setIsDelayed(false);\n }, 200);\n return () => clearTimeout(timer);\n }, []);\n\n useEffect(() => {\n const keyboardShowSubscription = Keyboard.addListener('keyboardDidShow', (e) => {\n if (scrollViewRef.current && keyboardScrollExtraOffset) {\n const screenHeight = Dimensions.get('window').height;\n const keyboardHeight = e.endCoordinates.height;\n const safeAreaBottom = 0;\n const availableScreenHeight = screenHeight - keyboardHeight - safeAreaBottom;\n const delta = (lastTouchY?.current || 0) + keyboardScrollExtraOffset - availableScreenHeight;\n\n scrollViewRef.current.scrollTo({\n y: (positionRef.current ?? 0) + delta,\n animated: true,\n });\n }\n });\n\n return () => {\n positionRef.current = null;\n lastTouchY.current = null;\n keyboardShowSubscription.remove();\n };\n }, [keyboardScrollExtraOffset]);\n\n const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (keyboardScrollExtraOffset) positionRef.current = event.nativeEvent.contentOffset.y;\n };\n\n const handleTouch = (evt: any) => {\n if (keyboardScrollExtraOffset) lastTouchY.current = evt.nativeEvent.pageY;\n };\n\n return (\n <SafeAreaView\n style={[\n { backgroundColor: backgroundColor || palette.background.base },\n styles.flex1,\n styles.fullWidth,\n ]}\n edges={edges}\n >\n {!isDelayed && (\n <KeyboardAvoidingView\n style={[styles.flex1, styles.fullWidth]}\n behavior={behavior}\n keyboardVerticalOffset={keyboardVerticalOffset}\n >\n {topComponent && topComponent}\n\n {isLoader ? (\n loadingComponent\n ) : isScrollView ? (\n <ScrollViewAtom\n ref={scrollViewRef}\n style={[styles.flex1, styles.fullWidth]}\n bounces={false}\n overScrollMode=\"never\"\n contentContainerStyle={styles.scrollContainerStyle}\n showsVerticalScrollIndicator={showsVerticalScrollIndicator}\n keyboardShouldPersistTaps=\"handled\"\n automaticallyAdjustKeyboardInsets={automaticallyAdjustKeyboardInsets}\n onScroll={handleScroll}\n onTouchStart={handleTouch}\n >\n <ViewAtom style={[styles.flex1, styles.fullWidth, props.style]}>\n {props.children}\n </ViewAtom>\n </ScrollViewAtom>\n ) : (\n <ViewAtom style={[styles.flex1, styles.fullWidth, props.style]}>\n {props.children}\n </ViewAtom>\n )}\n\n {!isLoader && bottomComponent && bottomComponent}\n </KeyboardAvoidingView>\n )}\n <StatusBar\n barStyle={barStyle}\n backgroundColor={statusBarColor || palette.background.base}\n />\n </SafeAreaView>\n );\n});\n\nconst styles = StyleSheet.create({\n flex1: { flex: 1 },\n fullWidth: { width: Dimensions.get('window').width },\n scrollContainerStyle: {\n flexGrow: 1,\n alignItems: 'center',\n width: Dimensions.get('window').width,\n },\n});\n\nexport default ZSContainer;\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/ZSContainer/index.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { ReactNode, useState, useEffect, useImperativeHandle, forwardRef, useRef } from 'react';\nimport { ViewProps, KeyboardAvoidingView, StatusBar, StyleSheet, Dimensions, ActivityIndicator, ScrollView, NativeSyntheticEvent, NativeScrollEvent, Keyboard } from 'react-native';\nimport { SafeAreaView } from 'react-native-safe-area-context';\nimport ViewAtom from '../atoms/ViewAtom';\nimport ScrollViewAtom from '../atoms/ScrollViewAtom';\nimport { useTheme } from '../../model/useThemeProvider';\n\nexport type ZSContainerProps = ViewProps & {\n backgroundColor?: string;\n isLoader?: boolean;\n statusBarColor?: string;\n barStyle?: 'light-content' | 'dark-content';\n edges?: Array<'top' | 'right' | 'bottom' | 'left'>;\n isScrollView?: boolean;\n topComponent?: ReactNode;\n bottomComponent?: ReactNode;\n showsVerticalScrollIndicator?: boolean;\n loadingComponent?: React.ReactNode;\n keyboardVerticalOffset?: number;\n behavior?: 'padding' | 'height' | 'position';\n automaticallyAdjustKeyboardInsets?: boolean;\n keyboardScrollExtraOffset?: number;\n};\n\nexport type ZSContainerRef = ScrollView;\n\nconst ZSContainer = forwardRef<ZSContainerRef, ZSContainerProps>(function ZSContainer(\n {\n backgroundColor,\n isLoader = false,\n statusBarColor,\n barStyle = 'dark-content',\n edges = ['top', 'bottom'],\n isScrollView = true,\n topComponent,\n bottomComponent,\n showsVerticalScrollIndicator = true,\n loadingComponent = <ActivityIndicator />,\n keyboardVerticalOffset,\n behavior,\n automaticallyAdjustKeyboardInsets = true,\n keyboardScrollExtraOffset,\n ...props\n },\n forwardedRef\n) {\n const { palette } = useTheme();\n const [isDelayed, setIsDelayed] = useState(true);\n const positionRef = useRef<number | null>(0);\n const scrollViewRef = useRef<ScrollView>(null);\n const lastTouchY = useRef<number | null>(0);\n\n useImperativeHandle(forwardedRef, () => scrollViewRef.current as ScrollView, []);\n\n useEffect(() => {\n const timer = setTimeout(() => {\n setIsDelayed(false);\n }, 200);\n return () => clearTimeout(timer);\n }, []);\n\n useEffect(() => {\n const keyboardShowSubscription = Keyboard.addListener('keyboardDidShow', (e) => {\n if (scrollViewRef.current && keyboardScrollExtraOffset) {\n const screenHeight = Dimensions.get('window').height;\n const keyboardHeight = e.endCoordinates.height;\n const safeAreaBottom = 0;\n const availableScreenHeight = screenHeight - keyboardHeight - safeAreaBottom;\n\n // 현재 터치 위치와 스크롤 위치를 기반으로 새로운 스크롤 위치 계산\n const currentScrollPosition = positionRef.current || 0;\n const touchPosition = lastTouchY.current || 0;\n\n const scrollOffset = touchPosition - availableScreenHeight + keyboardScrollExtraOffset;\n scrollViewRef.current.scrollTo({\n y: currentScrollPosition + scrollOffset,\n animated: true,\n });\n }\n });\n\n return () => {\n positionRef.current = null;\n lastTouchY.current = null;\n keyboardShowSubscription.remove();\n };\n }, [keyboardScrollExtraOffset]);\n\n const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>) => {\n if (keyboardScrollExtraOffset) positionRef.current = event.nativeEvent.contentOffset.y;\n };\n\n const handleTouch = (evt: any) => {\n if (keyboardScrollExtraOffset) lastTouchY.current = evt.nativeEvent.pageY;\n };\n\n return (\n <SafeAreaView\n style={[\n { backgroundColor: backgroundColor || palette.background.base },\n styles.flex1,\n styles.fullWidth,\n ]}\n edges={edges}\n >\n {!isDelayed && (\n <KeyboardAvoidingView\n style={[styles.flex1, styles.fullWidth]}\n behavior={behavior}\n keyboardVerticalOffset={keyboardVerticalOffset}\n >\n {topComponent && topComponent}\n\n {isLoader ? (\n loadingComponent\n ) : isScrollView ? (\n <ScrollViewAtom\n ref={scrollViewRef}\n style={[styles.flex1, styles.fullWidth]}\n bounces={false}\n overScrollMode=\"never\"\n contentContainerStyle={styles.scrollContainerStyle}\n showsVerticalScrollIndicator={showsVerticalScrollIndicator}\n keyboardShouldPersistTaps=\"handled\"\n automaticallyAdjustKeyboardInsets={automaticallyAdjustKeyboardInsets}\n onScroll={handleScroll}\n onTouchStart={handleTouch}\n >\n <ViewAtom style={[styles.flex1, styles.fullWidth, props.style]}>\n {props.children}\n </ViewAtom>\n </ScrollViewAtom>\n ) : (\n <ViewAtom style={[styles.flex1, styles.fullWidth, props.style]}>\n {props.children}\n </ViewAtom>\n )}\n\n {!isLoader && bottomComponent && bottomComponent}\n </KeyboardAvoidingView>\n )}\n <StatusBar\n barStyle={barStyle}\n backgroundColor={statusBarColor || palette.background.base}\n />\n </SafeAreaView>\n );\n});\n\nconst styles = StyleSheet.create({\n flex1: { flex: 1 },\n fullWidth: { width: Dimensions.get('window').width },\n scrollContainerStyle: {\n flexGrow: 1,\n alignItems: 'center',\n width: Dimensions.get('window').width,\n },\n});\n\nexport default ZSContainer;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0610studio/zs-ui",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "private": false,
5
5
  "description": "EXPO ZS-UI",
6
6
  "type": "module",