@codeleap/mobile 5.4.5 → 5.5.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 (53) hide show
  1. package/dist/components/CalendarInput/index.js +9 -23
  2. package/dist/components/CalendarInput/index.js.map +1 -1
  3. package/dist/components/FileInput/index.js +3 -20
  4. package/dist/components/FileInput/index.js.map +1 -1
  5. package/dist/components/FileInput/types.d.ts +0 -3
  6. package/dist/components/InputBase/index.d.ts +6 -2
  7. package/dist/components/InputBase/index.js +14 -26
  8. package/dist/components/InputBase/index.js.map +1 -1
  9. package/dist/components/InputBase/types.d.ts +2 -2
  10. package/dist/components/InputOverlay/index.d.ts +8 -0
  11. package/dist/components/InputOverlay/index.js +75 -0
  12. package/dist/components/InputOverlay/index.js.map +1 -0
  13. package/dist/components/InputOverlay/store.d.ts +10 -0
  14. package/dist/components/InputOverlay/store.js +47 -0
  15. package/dist/components/InputOverlay/store.js.map +1 -0
  16. package/dist/components/InputOverlay/types.d.ts +22 -0
  17. package/dist/components/InputOverlay/types.js +2 -0
  18. package/dist/components/InputOverlay/types.js.map +1 -0
  19. package/dist/components/Scroll/index.d.ts +10 -2
  20. package/dist/components/Scroll/index.js +6 -22
  21. package/dist/components/Scroll/index.js.map +1 -1
  22. package/dist/components/TextInput/index.d.ts +10 -2
  23. package/dist/components/TextInput/index.js +2 -3
  24. package/dist/components/TextInput/index.js.map +1 -1
  25. package/dist/components/TextInput/useTextInput.js +2 -0
  26. package/dist/components/TextInput/useTextInput.js.map +1 -1
  27. package/dist/components/TimeInput/index.js +9 -24
  28. package/dist/components/TimeInput/index.js.map +1 -1
  29. package/dist/components/components.d.ts +1 -0
  30. package/dist/components/components.js +1 -0
  31. package/dist/components/components.js.map +1 -1
  32. package/dist/modules/backgroundTimer.js +3 -4
  33. package/dist/modules/backgroundTimer.js.map +1 -1
  34. package/package.json +17 -17
  35. package/package.json.bak +1 -1
  36. package/src/components/CalendarInput/index.tsx +31 -42
  37. package/src/components/FileInput/index.tsx +2 -25
  38. package/src/components/FileInput/types.ts +0 -3
  39. package/src/components/InputBase/index.tsx +18 -36
  40. package/src/components/InputBase/types.ts +2 -2
  41. package/src/components/InputOverlay/index.tsx +113 -0
  42. package/src/components/InputOverlay/store.ts +60 -0
  43. package/src/components/InputOverlay/types.ts +25 -0
  44. package/src/components/Scroll/index.tsx +6 -39
  45. package/src/components/TextInput/index.tsx +2 -3
  46. package/src/components/TextInput/useTextInput.ts +2 -0
  47. package/src/components/TimeInput/index.tsx +28 -41
  48. package/src/components/components.ts +2 -1
  49. package/src/modules/backgroundTimer.ts +6 -7
  50. package/dist/components/InputBase/useInputOverlay.d.ts +0 -1
  51. package/dist/components/InputBase/useInputOverlay.js +0 -30
  52. package/dist/components/InputBase/useInputOverlay.js.map +0 -1
  53. package/src/components/InputBase/useInputOverlay.ts +0 -38
@@ -0,0 +1,113 @@
1
+ import React, { useCallback, useState } from 'react'
2
+ import { LayoutChangeEvent, StyleSheet, View } from 'react-native'
3
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler'
4
+ import Animated, { FadeOut, FadeIn } from 'react-native-reanimated'
5
+ import { inputOverlayManager } from './store'
6
+ import { DetectorProps, InterceptorProps, LayoutProps } from './types'
7
+
8
+ export * from './store'
9
+
10
+ const Detector = ({ children, style, withWrapper = true }: DetectorProps) => {
11
+ const tapGesture = Gesture.Tap()
12
+ .onEnd((event) => {
13
+ inputOverlayManager.closeAll()
14
+ })
15
+ .runOnJS(true)
16
+
17
+ if (!withWrapper) {
18
+ <GestureDetector gesture={tapGesture}>
19
+ {children}
20
+ </GestureDetector>
21
+ }
22
+
23
+ return (
24
+ <GestureDetector gesture={tapGesture}>
25
+ <View style={[style, styles.detectorContainer]}>
26
+ {children}
27
+ </View>
28
+ </GestureDetector>
29
+ )
30
+ }
31
+
32
+ const Interceptor = ({ children }: InterceptorProps) => {
33
+ const tapGesture = Gesture.Tap()
34
+ .onEnd(() => {
35
+ // Intercepts the tap to prevent it from propagating to the parent
36
+ // Does nothing, just consumes the event
37
+ })
38
+ .runOnJS(true)
39
+
40
+ return (
41
+ <GestureDetector gesture={tapGesture}>
42
+ {children}
43
+ </GestureDetector>
44
+ )
45
+ }
46
+
47
+ const Layout = (props: LayoutProps) => {
48
+ const {
49
+ style,
50
+ children,
51
+ hideOverlay = false,
52
+ isOpen,
53
+ animationDuration = 150,
54
+ mode = 'overlay',
55
+ position,
56
+ gap,
57
+ content,
58
+ id,
59
+ } = props
60
+
61
+ const [inputHeight, setInputHeight] = useState(0)
62
+
63
+ const handleLayout = useCallback((event: LayoutChangeEvent) => {
64
+ const height = event?.nativeEvent?.layout?.height ?? 0
65
+ setInputHeight(height)
66
+ }, [])
67
+
68
+ const isOverlayMode = mode === 'overlay'
69
+
70
+ const shouldShowOverlay = isOpen && !hideOverlay
71
+
72
+ const overlayStyle = isOverlayMode ? {
73
+ position: 'absolute' as const,
74
+ zIndex: 1,
75
+ [position]: 0,
76
+ top: inputHeight + gap,
77
+ } : {
78
+ marginTop: gap,
79
+ }
80
+
81
+ return (
82
+ <View style={[style, styles.layoutContainer]} onLayout={handleLayout}>
83
+ {children}
84
+
85
+ {shouldShowOverlay ? (
86
+ <Interceptor>
87
+ <Animated.View
88
+ exiting={FadeOut.duration(animationDuration)}
89
+ entering={FadeIn.duration(animationDuration)}
90
+ style={overlayStyle}
91
+ >
92
+ {content}
93
+ </Animated.View>
94
+ </Interceptor>
95
+ ) : null}
96
+ </View>
97
+ )
98
+ }
99
+
100
+ const styles = StyleSheet.create({
101
+ detectorContainer: {
102
+ flex: 1,
103
+ },
104
+ layoutContainer: {
105
+ position: 'relative',
106
+ },
107
+ })
108
+
109
+ export const InputOverlay = {
110
+ Detector,
111
+ Interceptor,
112
+ Layout,
113
+ }
@@ -0,0 +1,60 @@
1
+ import { useCallback, useRef } from 'react'
2
+ import { useId } from '@codeleap/hooks'
3
+ import { atom } from 'nanostores'
4
+ import { useStore } from '@nanostores/react'
5
+
6
+ const defaultValue = '@input.atom'
7
+
8
+ const inputIdAtom = atom<string>(defaultValue)
9
+
10
+ const closeInputOverlays = () => {
11
+ const currentInputId = inputIdAtom.get()
12
+
13
+ if (currentInputId === defaultValue) return
14
+
15
+ setTimeout(() => inputIdAtom.set(defaultValue), 100)
16
+ }
17
+
18
+ const toggleOverlay = (id: string) => {
19
+ const currentInputId = inputIdAtom.get()
20
+
21
+ const isOpen = currentInputId === id
22
+
23
+ inputIdAtom.set(isOpen ? defaultValue : id)
24
+ }
25
+
26
+ const useInputOverlay = (providedId?: string) => {
27
+ const id = useId(providedId)
28
+
29
+ const isCurrentlyOpen = useStore(inputIdAtom) === id
30
+
31
+ const toggle = useCallback(() => {
32
+ const currentInputId = inputIdAtom.get()
33
+
34
+ const isAnyOtherOpen = currentInputId !== defaultValue && currentInputId !== id
35
+ const isOpen = currentInputId === id
36
+
37
+ if (isAnyOtherOpen && !isOpen) {
38
+ inputIdAtom.set(defaultValue)
39
+
40
+ setTimeout(() => {
41
+ inputIdAtom.set(id)
42
+ }, 100)
43
+ } else {
44
+ inputIdAtom.set(isOpen ? defaultValue : id)
45
+ }
46
+ }, [id])
47
+
48
+ return {
49
+ id,
50
+ isOpen: isCurrentlyOpen,
51
+ toggle,
52
+ }
53
+ }
54
+
55
+ export const inputOverlayManager = {
56
+ store: inputIdAtom,
57
+ use: useInputOverlay,
58
+ toggle: toggleOverlay,
59
+ closeAll: closeInputOverlays,
60
+ }
@@ -0,0 +1,25 @@
1
+ import React from 'react'
2
+ import { ViewStyle } from 'react-native'
3
+
4
+ export type DetectorProps = {
5
+ children: React.ReactNode
6
+ style?: any
7
+ withWrapper?: boolean
8
+ }
9
+
10
+ export type InterceptorProps = {
11
+ children: React.ReactNode
12
+ }
13
+
14
+ export type LayoutProps = {
15
+ style?: ViewStyle
16
+ hideOverlay?: boolean
17
+ mode: 'overlay' | 'content'
18
+ isOpen: boolean
19
+ position: 'left' | 'right' | 'center'
20
+ gap: number
21
+ animationDuration?: number
22
+ children: React.ReactNode
23
+ content: React.ReactNode
24
+ id: string
25
+ }
@@ -1,8 +1,7 @@
1
- import React, { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react'
1
+ import React, { useRef } from 'react'
2
2
  import { ScrollView } from 'react-native'
3
- import { RefreshControl } from '../RefreshControl'
4
- import { ScrollProps, ScrollRef } from './types'
5
- import { AnyRecord, IJSX, StyledComponentProps, StyledComponentWithProps } from '@codeleap/styles'
3
+ import { ScrollProps } from './types'
4
+ import { AnyRecord, IJSX, StyledComponentProps } from '@codeleap/styles'
6
5
  import { MobileStyleRegistry } from '../../Registry'
7
6
  import { useStylesFor } from '../../hooks'
8
7
  import { KeyboardAwareScrollView } from 'react-native-keyboard-controller'
@@ -11,7 +10,7 @@ import { ScrollProvider, useScrollPubSub } from '../../modules/scroll'
11
10
  export * from './styles'
12
11
  export * from './types'
13
12
 
14
- export const Scroll = forwardRef<ScrollRef, ScrollProps>((scrollProps, ref) => {
13
+ export const Scroll = (scrollProps: ScrollProps) => {
15
14
  const {
16
15
  style,
17
16
  refreshTimeout,
@@ -19,59 +18,27 @@ export const Scroll = forwardRef<ScrollRef, ScrollProps>((scrollProps, ref) => {
19
18
  refreshControlProps = {},
20
19
  contentContainerStyle,
21
20
  keyboardAware,
22
- onRefresh: onRefresh,
23
21
  ...props
24
22
  } = {
25
23
  ...Scroll.defaultProps,
26
24
  ...scrollProps,
27
25
  }
28
26
 
29
- const hasRefresh = !!onRefresh
30
- const [refreshing, setRefreshing] = useState(false)
31
- const refreshingDisplay = props.refreshing !== undefined ? props.refreshing : refreshing
32
-
33
- const timer = React.useRef(null)
34
-
35
- const refresh = useCallback(() => {
36
- if (timer.current !== null) {
37
- clearTimeout(timer.current)
38
- timer.current = null
39
- }
40
-
41
- setRefreshing(true)
42
-
43
- onRefresh?.()
44
-
45
- timer.current = setTimeout(() => {
46
- setRefreshing(false)
47
- }, refreshTimeout)
48
- }, [onRefresh])
49
-
50
27
  const styles = useStylesFor(Scroll.styleRegistryName, style)
51
28
 
52
29
  const Component = keyboardAware ? KeyboardAwareScrollView : ScrollView
53
30
 
54
31
  const _scrollRef = useRef<ScrollView>()
55
32
 
33
+ // @ts-ignore
56
34
  const { ref: scrollRef, emit } = useScrollPubSub(_scrollRef)
57
35
 
58
- useImperativeHandle(ref, () => scrollRef.current as unknown as ScrollView, [])
59
-
60
36
  return (
61
37
  <ScrollProvider ref={scrollRef}>
62
38
  <Component
63
39
  showsVerticalScrollIndicator={false}
64
40
  // @ts-ignore
65
41
  ref={_scrollRef}
66
- refreshControl={
67
- hasRefresh && (
68
- <RefreshControl
69
- refreshing={refreshingDisplay}
70
- onRefresh={refresh}
71
- {...refreshControlProps}
72
- />
73
- )
74
- }
75
42
  bottomOffset={30}
76
43
  {...props}
77
44
  style={styles?.wrapper}
@@ -85,7 +52,7 @@ export const Scroll = forwardRef<ScrollRef, ScrollProps>((scrollProps, ref) => {
85
52
  </Component>
86
53
  </ScrollProvider>
87
54
  )
88
- }) as StyledComponentWithProps<ScrollProps>
55
+ }
89
56
 
90
57
  Scroll.styleRegistryName = 'Scroll'
91
58
  Scroll.elements = ['wrapper', 'content']
@@ -1,6 +1,5 @@
1
1
  import React from 'react'
2
2
  import { TypeGuards } from '@codeleap/types'
3
- import { forwardRef } from 'react'
4
3
  import { TextInput as NativeTextInput } from 'react-native'
5
4
  import { InputBase, selectInputBaseProps } from '../InputBase'
6
5
  import { Touchable } from '../Touchable'
@@ -15,7 +14,7 @@ import { useInputBasePartialStyles } from '../InputBase/useInputBasePartialStyle
15
14
  export * from './styles'
16
15
  export * from './types'
17
16
 
18
- export const TextInput = forwardRef<NativeTextInput, TextInputProps>((props, inputRef) => {
17
+ export const TextInput = (props: TextInputProps) => {
19
18
  const allProps = {
20
19
  ...TextInput.defaultProps,
21
20
  ...props,
@@ -155,7 +154,7 @@ export const TextInput = forwardRef<NativeTextInput, TextInputProps>((props, inp
155
154
  {...maskingExtraProps}
156
155
  />
157
156
  </InputBase>
158
- }) as StyledComponentWithProps<TextInputProps>
157
+ }
159
158
 
160
159
  TextInput.styleRegistryName = 'TextInput'
161
160
  TextInput.elements = [...InputBase.elements, 'input', 'placeholder', 'selection']
@@ -3,6 +3,7 @@ import { TextInputProps } from './types'
3
3
  import { NativeSyntheticEvent, TextInputFocusEventData } from 'react-native/types'
4
4
  import { useInputBase } from '../InputBase/useInputBase'
5
5
  import { fields } from '@codeleap/form'
6
+ import { inputOverlayManager } from '../InputOverlay'
6
7
 
7
8
  export function useTextInput(props: Partial<TextInputProps>) {
8
9
  const {
@@ -58,6 +59,7 @@ export function useTextInput(props: Partial<TextInputProps>) {
58
59
  setIsFocused(true)
59
60
  if (autoAdjustSelection) setCurrentSelection(null)
60
61
  onFocus?.(e)
62
+ inputOverlayManager.closeAll()
61
63
  }, [onFocus])
62
64
 
63
65
  const handleMaskChange = useCallback((masked, unmasked) => {
@@ -1,8 +1,7 @@
1
- import React, { useState } from 'react'
1
+ import React from 'react'
2
2
  import { AnyRecord, IJSX, StyledComponentProps, useCompositionStyles } from '@codeleap/styles'
3
3
  import { TimeInputProps } from './types'
4
4
  import dayjs from 'dayjs'
5
- import Animated, { FadeOut, FadeIn } from 'react-native-reanimated'
6
5
  import { fields } from '@codeleap/form'
7
6
  import DatePicker from 'react-native-date-picker'
8
7
  import { useStylesFor } from '../../hooks'
@@ -10,7 +9,7 @@ import { useInputBase } from '../InputBase'
10
9
  import { View } from '../View'
11
10
  import { TextInput } from '../TextInput'
12
11
  import { MobileStyleRegistry } from '../../Registry'
13
- import { useInputOverlay } from '../InputBase/useInputOverlay'
12
+ import { InputOverlay, inputOverlayManager } from '../InputOverlay'
14
13
 
15
14
  export * from './styles'
16
15
  export * from './types'
@@ -45,17 +44,38 @@ export const TimeInput = (props: TimeInputProps) => {
45
44
  onInputValueChange,
46
45
  } = useInputBase<Date>(field, fields.date as any, { value, onValueChange })
47
46
 
48
- const [inputHeight, setInputHeight] = useState(0)
49
-
50
- const [isOpen, toggle] = useInputOverlay(autoClosePeersOverlays)
47
+ const { isOpen, toggle, id } = inputOverlayManager.use()
51
48
 
52
49
  return (
53
- <View style={[styles.wrapper, { position: 'relative' }]}>
50
+ <InputOverlay.Layout
51
+ style={styles.wrapper}
52
+ position={timePickerPosition}
53
+ gap={gap}
54
+ isOpen={isOpen}
55
+ mode={overlay ? 'overlay' : 'content'}
56
+ hideOverlay={disabled}
57
+ id={id}
58
+ content={
59
+ <View style={styles.timePicker}>
60
+ <DatePicker
61
+ mode='time'
62
+ theme='light'
63
+ {...timePickerProps}
64
+ onDateChange={onInputValueChange}
65
+ date={inputValue ?? new Date()}
66
+ />
67
+ </View>
68
+ }
69
+ >
54
70
  <TextInput
55
71
  placeholder='Select a time'
56
72
  disabled={disabled}
57
73
  {...textInputProps}
58
74
  style={compositionStyles.input}
75
+ value={!inputValue ? '' : dayjs(inputValue).format(format)}
76
+ onValueChange={() => inputValue}
77
+ onPress={disabled ? undefined : toggle}
78
+ focused={isOpen}
59
79
  leftIcon={!leftIcon ? null : {
60
80
  ...leftIcon,
61
81
  onPress: toggle,
@@ -64,41 +84,8 @@ export const TimeInput = (props: TimeInputProps) => {
64
84
  ...rightIcon,
65
85
  onPress: toggle,
66
86
  }}
67
- value={!inputValue ? '' : dayjs(inputValue).format(format)}
68
- onValueChange={() => inputValue}
69
- onPress={disabled ? null : toggle}
70
- innerWrapperProps={{
71
- rippleDisabled: true,
72
- }}
73
- focused={isOpen}
74
- onLayout={(e) => setInputHeight(e.nativeEvent.layout.height)}
75
87
  />
76
-
77
- {!isOpen || disabled ? null : (
78
- <Animated.View
79
- exiting={FadeOut.duration(150)}
80
- entering={FadeIn.duration(150)}
81
- style={overlay ? {
82
- position: 'absolute',
83
- zIndex: 1,
84
- [timePickerPosition]: 0,
85
- top: inputHeight + gap,
86
- } : {
87
- marginTop: gap,
88
- }}
89
- >
90
- <View style={styles.timePicker}>
91
- <DatePicker
92
- mode='time'
93
- theme='light'
94
- {...timePickerProps}
95
- onDateChange={onInputValueChange}
96
- date={inputValue ?? new Date()}
97
- />
98
- </View>
99
- </Animated.View>
100
- )}
101
- </View>
88
+ </InputOverlay.Layout>
102
89
  )
103
90
  }
104
91
 
@@ -41,4 +41,5 @@ export * from './SortablePhotos'
41
41
  export * from './SectionFilters'
42
42
  export * from './Tabs'
43
43
  export * from './CalendarInput'
44
- export * from './TimeInput'
44
+ export * from './TimeInput'
45
+ export * from './InputOverlay'
@@ -1,17 +1,16 @@
1
1
  import { AnyFunction } from '@codeleap/types'
2
- import BackgroundTimer from '@boterop/react-native-background-timer'
3
2
  import { uuid } from '..'
4
3
 
5
4
  const throttleTimerId = {}
6
5
 
7
- export function throttle(func:AnyFunction, ref?: string, delay = 200) {
6
+ export function throttle(func: AnyFunction, ref?: string, delay = 200) {
8
7
  if (!ref) {
9
8
  ref = uuid.v4() as string
10
9
  }
11
10
  if (throttleTimerId[ref]) {
12
11
  return
13
12
  }
14
- throttleTimerId[ref] = BackgroundTimer.setTimeout(function () {
13
+ throttleTimerId[ref] = setTimeout(function () {
15
14
  func()
16
15
  throttleTimerId[ref] = undefined
17
16
  }, delay)
@@ -21,19 +20,19 @@ export function throttle(func:AnyFunction, ref?: string, delay = 200) {
21
20
 
22
21
  const debounceTimerId = {}
23
22
 
24
- export function debounce(func:AnyFunction, ref?: string, delay = 200) {
23
+ export function debounce(func: AnyFunction, ref?: string, delay = 200) {
25
24
  if (!ref) {
26
25
  ref = uuid.v4() as string
27
26
  }
28
27
 
29
28
  if (debounceTimerId[ref]) {
30
- BackgroundTimer.clearTimeout(debounceTimerId[ref])
29
+ clearTimeout(debounceTimerId[ref])
31
30
  }
32
31
 
33
- debounceTimerId[ref] = BackgroundTimer.setTimeout(function () {
32
+ debounceTimerId[ref] = setTimeout(function () {
34
33
  func()
35
34
  debounceTimerId[ref] = undefined
36
35
  }, delay)
37
36
 
38
37
  return ref
39
- }
38
+ }
@@ -1 +0,0 @@
1
- export declare const useInputOverlay: (autoClosePeersOverlays: boolean, providedId?: string) => any[] | readonly [boolean, (value?: boolean) => void];
@@ -1,30 +0,0 @@
1
- import { useBooleanToggle } from '@codeleap/hooks';
2
- import { globalState } from '@codeleap/store';
3
- import { useCallback } from 'react';
4
- import { useId } from '@codeleap/hooks';
5
- const inputOverlayStore = globalState({});
6
- export const useInputOverlay = (autoClosePeersOverlays, providedId) => {
7
- if (!autoClosePeersOverlays)
8
- return useBooleanToggle(false);
9
- const id = useId(providedId);
10
- const isOpen = inputOverlayStore.use(state => state[id]);
11
- const toggle = useCallback(() => {
12
- const isCurrentlyOpen = inputOverlayStore.value[id];
13
- const isAnyOtherOpen = Object.entries(inputOverlayStore.value).some(([key, isOpen]) => key !== id && isOpen);
14
- const newValues = Object.keys(inputOverlayStore.value).reduce((acc, key) => {
15
- acc[key] = false;
16
- return acc;
17
- }, {});
18
- if (isAnyOtherOpen && !isCurrentlyOpen) {
19
- inputOverlayStore.set(newValues);
20
- setTimeout(() => {
21
- inputOverlayStore.set({ [id]: true });
22
- }, 100);
23
- }
24
- else {
25
- inputOverlayStore.set({ ...newValues, [id]: !isCurrentlyOpen });
26
- }
27
- }, []);
28
- return [isOpen, toggle];
29
- };
30
- //# sourceMappingURL=useInputOverlay.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useInputOverlay.js","sourceRoot":"","sources":["../../../src/components/InputBase/useInputOverlay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,MAAM,iBAAiB,GAAG,WAAW,CAAC,EAAE,CAAC,CAAA;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,sBAA+B,EAAE,UAAmB,EAAE,EAAE;IACtF,IAAI,CAAC,sBAAsB;QAAE,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAE3D,MAAM,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,CAAA;IAE5B,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAA;IAExD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,MAAM,eAAe,GAAG,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QACnD,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,IAAI,CACjE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,EAAE,IAAI,MAAM,CACxC,CAAA;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACzE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;YAChB,OAAO,GAAG,CAAA;QACZ,CAAC,EAAE,EAA6B,CAAC,CAAA;QAEjC,IAAI,cAAc,IAAI,CAAC,eAAe,EAAE;YACtC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;YAEhC,UAAU,CAAC,GAAG,EAAE;gBACd,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;YACvC,CAAC,EAAE,GAAG,CAAC,CAAA;SACR;aAAM;YACL,iBAAiB,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,CAAA;SAChE;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AACzB,CAAC,CAAA"}
@@ -1,38 +0,0 @@
1
- import { useBooleanToggle } from '@codeleap/hooks'
2
- import { globalState } from '@codeleap/store'
3
- import { useCallback } from 'react'
4
- import { useId } from '@codeleap/hooks'
5
-
6
- const inputOverlayStore = globalState({})
7
-
8
- export const useInputOverlay = (autoClosePeersOverlays: boolean, providedId?: string) => {
9
- if (!autoClosePeersOverlays) return useBooleanToggle(false)
10
-
11
- const id = useId(providedId)
12
-
13
- const isOpen = inputOverlayStore.use(state => state[id])
14
-
15
- const toggle = useCallback(() => {
16
- const isCurrentlyOpen = inputOverlayStore.value[id]
17
- const isAnyOtherOpen = Object.entries(inputOverlayStore.value).some(
18
- ([key, isOpen]) => key !== id && isOpen
19
- )
20
-
21
- const newValues = Object.keys(inputOverlayStore.value).reduce((acc, key) => {
22
- acc[key] = false
23
- return acc
24
- }, {} as Record<string, boolean>)
25
-
26
- if (isAnyOtherOpen && !isCurrentlyOpen) {
27
- inputOverlayStore.set(newValues)
28
-
29
- setTimeout(() => {
30
- inputOverlayStore.set({ [id]: true })
31
- }, 100)
32
- } else {
33
- inputOverlayStore.set({ ...newValues, [id]: !isCurrentlyOpen })
34
- }
35
- }, [])
36
-
37
- return [isOpen, toggle]
38
- }