@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.
- package/dist/components/CalendarInput/index.js +9 -23
- package/dist/components/CalendarInput/index.js.map +1 -1
- package/dist/components/FileInput/index.js +3 -20
- package/dist/components/FileInput/index.js.map +1 -1
- package/dist/components/FileInput/types.d.ts +0 -3
- package/dist/components/InputBase/index.d.ts +6 -2
- package/dist/components/InputBase/index.js +14 -26
- package/dist/components/InputBase/index.js.map +1 -1
- package/dist/components/InputBase/types.d.ts +2 -2
- package/dist/components/InputOverlay/index.d.ts +8 -0
- package/dist/components/InputOverlay/index.js +75 -0
- package/dist/components/InputOverlay/index.js.map +1 -0
- package/dist/components/InputOverlay/store.d.ts +10 -0
- package/dist/components/InputOverlay/store.js +47 -0
- package/dist/components/InputOverlay/store.js.map +1 -0
- package/dist/components/InputOverlay/types.d.ts +22 -0
- package/dist/components/InputOverlay/types.js +2 -0
- package/dist/components/InputOverlay/types.js.map +1 -0
- package/dist/components/Scroll/index.d.ts +10 -2
- package/dist/components/Scroll/index.js +6 -22
- package/dist/components/Scroll/index.js.map +1 -1
- package/dist/components/TextInput/index.d.ts +10 -2
- package/dist/components/TextInput/index.js +2 -3
- package/dist/components/TextInput/index.js.map +1 -1
- package/dist/components/TextInput/useTextInput.js +2 -0
- package/dist/components/TextInput/useTextInput.js.map +1 -1
- package/dist/components/TimeInput/index.js +9 -24
- package/dist/components/TimeInput/index.js.map +1 -1
- package/dist/components/components.d.ts +1 -0
- package/dist/components/components.js +1 -0
- package/dist/components/components.js.map +1 -1
- package/dist/modules/backgroundTimer.js +3 -4
- package/dist/modules/backgroundTimer.js.map +1 -1
- package/package.json +17 -17
- package/package.json.bak +1 -1
- package/src/components/CalendarInput/index.tsx +31 -42
- package/src/components/FileInput/index.tsx +2 -25
- package/src/components/FileInput/types.ts +0 -3
- package/src/components/InputBase/index.tsx +18 -36
- package/src/components/InputBase/types.ts +2 -2
- package/src/components/InputOverlay/index.tsx +113 -0
- package/src/components/InputOverlay/store.ts +60 -0
- package/src/components/InputOverlay/types.ts +25 -0
- package/src/components/Scroll/index.tsx +6 -39
- package/src/components/TextInput/index.tsx +2 -3
- package/src/components/TextInput/useTextInput.ts +2 -0
- package/src/components/TimeInput/index.tsx +28 -41
- package/src/components/components.ts +2 -1
- package/src/modules/backgroundTimer.ts +6 -7
- package/dist/components/InputBase/useInputOverlay.d.ts +0 -1
- package/dist/components/InputBase/useInputOverlay.js +0 -30
- package/dist/components/InputBase/useInputOverlay.js.map +0 -1
- 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, {
|
|
1
|
+
import React, { useRef } from 'react'
|
|
2
2
|
import { ScrollView } from 'react-native'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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 =
|
|
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
|
-
}
|
|
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 =
|
|
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
|
-
}
|
|
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
|
|
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 {
|
|
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
|
|
49
|
-
|
|
50
|
-
const [isOpen, toggle] = useInputOverlay(autoClosePeersOverlays)
|
|
47
|
+
const { isOpen, toggle, id } = inputOverlayManager.use()
|
|
51
48
|
|
|
52
49
|
return (
|
|
53
|
-
<
|
|
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
|
|
|
@@ -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] =
|
|
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
|
-
|
|
29
|
+
clearTimeout(debounceTimerId[ref])
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
debounceTimerId[ref] =
|
|
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
|
-
}
|