@neko-os/ui 0.0.8 → 0.0.10
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/DynamicStyleTag.js +5 -0
- package/dist/DynamicStyleTag.native.js +1 -0
- package/dist/NekoUI.js +1 -1
- package/dist/abstractions/ActivityIndicator.native.js +1 -1
- package/dist/abstractions/ActivityIndicator.web.js +1 -0
- package/dist/abstractions/AnimatedView.web.js +1 -0
- package/dist/abstractions/BlurView.web.js +1 -0
- package/dist/abstractions/FlatList.js +1 -0
- package/dist/abstractions/FlatList.native.js +1 -0
- package/dist/abstractions/FlatList.web.js +1 -0
- package/dist/abstractions/ScrollView.web.js +1 -0
- package/dist/abstractions/StaticList.js +1 -0
- package/dist/abstractions/helpers/storage.js +1 -0
- package/dist/abstractions/helpers/storage.native.js +1 -0
- package/dist/abstractions/helpers/useSafeAreaInsets.js +1 -0
- package/dist/abstractions/helpers/useSafeAreaInsets.native.js +1 -0
- package/dist/components/actions/Button.js +1 -1
- package/dist/components/actions/Dropdown.js +1 -1
- package/dist/components/actions/FloatingButton.js +1 -0
- package/dist/components/actions/index.js +1 -1
- package/dist/components/actions/menu/VerticalMenu.js +1 -1
- package/dist/components/calendar/_helpers/calendarDays.js +1 -1
- package/dist/components/feedback/alerter.js +1 -1
- package/dist/components/feedback/confirmer.js +1 -1
- package/dist/components/helpers/ConditionalLazyRender.js +1 -0
- package/dist/components/helpers/LazyAction.js +1 -0
- package/dist/components/helpers/LazyRender.js +1 -1
- package/dist/components/helpers/LazyRender.native.js +1 -1
- package/dist/components/helpers/index.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/inputs/DateInput.js +1 -1
- package/dist/components/inputs/InputWrapper.js +1 -1
- package/dist/components/inputs/LinkInput.js +1 -1
- package/dist/components/inputs/NumberInput.js +1 -0
- package/dist/components/inputs/Picker.js +1 -1
- package/dist/components/inputs/Radio.js +1 -1
- package/dist/components/inputs/RateInput.js +1 -0
- package/dist/components/inputs/SegmentedPicker.js +1 -0
- package/dist/components/inputs/Select.js +1 -0
- package/dist/components/inputs/datePicker/DayPicker.js +1 -1
- package/dist/components/inputs/datePicker/MonthPicker.js +1 -1
- package/dist/components/inputs/datePicker/QuarterPicker.js +1 -1
- package/dist/components/inputs/datePicker/WeekPicker.js +1 -1
- package/dist/components/inputs/datePicker/YearPicker.js +1 -1
- package/dist/components/inputs/index.js +1 -1
- package/dist/components/layout/Layout.js +1 -1
- package/dist/components/list/FlatList.js +1 -0
- package/dist/components/list/index.js +1 -1
- package/dist/components/presentation/Rate.js +1 -0
- package/dist/components/presentation/RateTag.js +1 -0
- package/dist/components/presentation/Result.js +1 -1
- package/dist/components/presentation/Tooltip.js +1 -1
- package/dist/components/presentation/index.js +1 -1
- package/dist/components/state/LoadingView.js +1 -1
- package/dist/components/structure/Accordion.js +1 -1
- package/dist/components/structure/Row.js +1 -1
- package/dist/components/structure/Segment.js +1 -0
- package/dist/components/structure/View.js +1 -1
- package/dist/components/structure/bottomDrawer/native/BottomDrawer.js +1 -1
- package/dist/components/structure/bottomDrawer/native/utils.js +1 -1
- package/dist/components/structure/bottomDrawer/web/BottomDrawer.js +1 -1
- package/dist/components/structure/index.js +1 -1
- package/dist/components/structure/overlay/OverlayHandler.js +1 -1
- package/dist/components/structure/popover/Popover.js +1 -1
- package/dist/components/structure/popover/Popover.native.js +1 -1
- package/dist/components/structure/popover/Popover_BU.js +1 -0
- package/dist/components/tabs/ActiveTabContent.js +1 -0
- package/dist/components/tabs/TabsHandler.js +1 -0
- package/dist/components/tabs/TabsMenu.js +1 -0
- package/dist/components/tabs/index.js +1 -0
- package/dist/components/theme/ThemePicker.js +1 -0
- package/dist/components/theme/ThemePickerDrawer.js +1 -0
- package/dist/components/theme/ThemeStatusBar.js +1 -0
- package/dist/components/theme/ThemeStatusBar.native.js +1 -0
- package/dist/components/theme/ThemeThumb.js +1 -0
- package/dist/components/theme/index.js +1 -0
- package/dist/helpers/index.js +1 -1
- package/dist/helpers/storage.js +1 -0
- package/dist/helpers/string.js +1 -1
- package/dist/i18n/I18n.js +1 -0
- package/dist/i18n/I18nProvider.js +1 -0
- package/dist/i18n/index.js +1 -0
- package/dist/index.css +4 -0
- package/dist/index.js +1 -1
- package/dist/modifiers/animations/fadeEffect.web.js +1 -0
- package/dist/modifiers/animations/scrollEffect.web.js +1 -0
- package/dist/modifiers/animations/slideEffect.web.js +1 -0
- package/dist/modifiers/fullColor.js +1 -1
- package/dist/modifiers/overflow.js +1 -1
- package/dist/modifiers/position.js +1 -1
- package/dist/theme/ThemeHandler.js +1 -1
- package/dist/theme/default/base.js +1 -1
- package/dist/theme/default/blackTheme.js +1 -1
- package/dist/theme/default/cyberpunkTheme.js +1 -1
- package/dist/theme/default/darkTheme.js +1 -1
- package/dist/theme/default/deepWoodsTheme.js +1 -1
- package/dist/theme/default/forestTheme.js +1 -1
- package/dist/theme/default/hackerTheme.js +1 -1
- package/dist/theme/default/lightTheme.js +1 -1
- package/dist/theme/default/midnightTheme.js +1 -1
- package/dist/theme/default/msdosTheme.js +1 -1
- package/dist/theme/default/oceanTheme.js +1 -1
- package/dist/theme/default/paperTheme.js +1 -0
- package/dist/theme/default/pastelTheme.js +1 -1
- package/dist/theme/default/sunsetTheme.js +1 -1
- package/dist/theme/default/themes.js +1 -1
- package/dist/theme/format/formatTheme.js +1 -1
- package/dist/theme/helpers/contrastColor.js +1 -1
- package/package.json +1 -1
- package/src/DynamicStyleTag.js +21 -0
- package/src/DynamicStyleTag.native.js +3 -0
- package/src/NekoUI.js +21 -4
- package/src/abstractions/ActivityIndicator.native.js +3 -4
- package/src/abstractions/ActivityIndicator.web.js +43 -0
- package/src/abstractions/AnimatedView.web.js +3 -0
- package/src/abstractions/BlurView.web.js +39 -0
- package/src/abstractions/FlatList.js +3 -0
- package/src/abstractions/FlatList.native.js +36 -0
- package/src/abstractions/FlatList.web.js +3 -0
- package/src/abstractions/ScrollView.web.js +3 -0
- package/src/abstractions/StaticList.js +51 -0
- package/src/abstractions/Text.web.js +15 -0
- package/src/abstractions/helpers/storage.js +32 -0
- package/src/abstractions/helpers/storage.native.js +34 -0
- package/src/abstractions/helpers/useSafeAreaInsets.js +3 -0
- package/src/abstractions/helpers/useSafeAreaInsets.native.js +3 -0
- package/src/components/actions/Button.js +1 -0
- package/src/components/actions/Dropdown.js +24 -5
- package/src/components/actions/FloatingButton.js +87 -0
- package/src/components/actions/index.js +1 -0
- package/src/components/actions/menu/VerticalMenu.js +30 -5
- package/src/components/calendar/_helpers/calendarDays.js +2 -0
- package/src/components/feedback/alerter.js +1 -1
- package/src/components/feedback/confirmer.js +2 -2
- package/src/components/helpers/ConditionalLazyRender.js +6 -0
- package/src/components/helpers/LazyAction.js +22 -0
- package/src/components/helpers/LazyRender.js +2 -2
- package/src/components/helpers/LazyRender.native.js +1 -1
- package/src/components/helpers/index.js +1 -0
- package/src/components/index.js +2 -0
- package/src/components/inputs/DateInput.js +11 -1
- package/src/components/inputs/InputWrapper.js +0 -1
- package/src/components/inputs/LinkInput.js +3 -3
- package/src/components/inputs/NumberInput.js +105 -0
- package/src/components/inputs/Picker.js +61 -9
- package/src/components/inputs/Radio.js +1 -1
- package/src/components/inputs/RateInput.js +62 -0
- package/src/components/inputs/SegmentedPicker.js +62 -0
- package/src/components/inputs/Select.js +189 -0
- package/src/components/inputs/datePicker/DayPicker.js +4 -5
- package/src/components/inputs/datePicker/MonthPicker.js +2 -2
- package/src/components/inputs/datePicker/QuarterPicker.js +2 -2
- package/src/components/inputs/datePicker/WeekPicker.js +2 -2
- package/src/components/inputs/datePicker/YearPicker.js +9 -6
- package/src/components/inputs/index.js +4 -0
- package/src/components/layout/Layout.js +1 -1
- package/src/components/list/FlatList.js +91 -0
- package/src/components/list/index.js +1 -0
- package/src/components/presentation/Rate.js +58 -0
- package/src/components/presentation/RateTag.js +35 -0
- package/src/components/presentation/Result.js +2 -2
- package/src/components/presentation/Tooltip.js +1 -0
- package/src/components/presentation/index.js +2 -0
- package/src/components/state/LoadingView.js +10 -1
- package/src/components/structure/Accordion.js +1 -1
- package/src/components/structure/Row.js +9 -1
- package/src/components/structure/Segment.js +51 -0
- package/src/components/structure/View.js +2 -0
- package/src/components/structure/bottomDrawer/native/BottomDrawer.js +19 -3
- package/src/components/structure/bottomDrawer/native/utils.js +29 -22
- package/src/components/structure/bottomDrawer/web/BottomDrawer.js +3 -1
- package/src/components/structure/index.js +1 -0
- package/src/components/structure/overlay/OverlayHandler.js +6 -1
- package/src/components/structure/popover/Popover.js +44 -21
- package/src/components/structure/popover/Popover.native.js +3 -2
- package/src/components/structure/popover/Popover_BU.js +157 -0
- package/src/components/tabs/ActiveTabContent.js +35 -0
- package/src/components/tabs/TabsHandler.js +16 -0
- package/src/components/tabs/TabsMenu.js +15 -0
- package/src/components/tabs/index.js +3 -0
- package/src/components/theme/ThemePicker.js +49 -0
- package/src/components/theme/ThemePickerDrawer.js +13 -0
- package/src/components/theme/ThemeStatusBar.js +3 -0
- package/src/components/theme/ThemeStatusBar.native.js +9 -0
- package/src/components/theme/ThemeThumb.js +98 -0
- package/src/components/theme/index.js +3 -0
- package/src/helpers/index.js +1 -0
- package/src/helpers/storage.js +54 -0
- package/src/helpers/string.js +18 -1
- package/src/i18n/I18n.js +97 -0
- package/src/i18n/I18nProvider.js +40 -0
- package/src/i18n/index.js +2 -0
- package/src/index.css +4 -0
- package/src/index.js +1 -0
- package/src/modifiers/animations/fadeEffect.web.js +3 -0
- package/src/modifiers/animations/scrollEffect.web.js +3 -0
- package/src/modifiers/animations/slideEffect.web.js +3 -0
- package/src/modifiers/fullColor.js +2 -2
- package/src/modifiers/overflow.js +6 -1
- package/src/modifiers/position.js +7 -0
- package/src/theme/ThemeHandler.js +18 -2
- package/src/theme/default/base.js +12 -8
- package/src/theme/default/blackTheme.js +4 -1
- package/src/theme/default/cyberpunkTheme.js +3 -1
- package/src/theme/default/darkTheme.js +3 -1
- package/src/theme/default/deepWoodsTheme.js +4 -2
- package/src/theme/default/forestTheme.js +3 -1
- package/src/theme/default/hackerTheme.js +3 -1
- package/src/theme/default/lightTheme.js +3 -1
- package/src/theme/default/midnightTheme.js +3 -1
- package/src/theme/default/msdosTheme.js +18 -4
- package/src/theme/default/oceanTheme.js +4 -2
- package/src/theme/default/paperTheme.js +35 -0
- package/src/theme/default/pastelTheme.js +3 -1
- package/src/theme/default/sunsetTheme.js +5 -3
- package/src/theme/default/themes.js +7 -10
- package/src/theme/format/formatTheme.js +9 -3
- package/src/theme/helpers/contrastColor.js +49 -11
- package/dist/abstractions/TouchableOpacity.web.js +0 -1
- package/src/abstractions/TouchableOpacity.web.js +0 -3
|
@@ -15,11 +15,14 @@ export function Popover({
|
|
|
15
15
|
parentWidth,
|
|
16
16
|
parentMinWidth,
|
|
17
17
|
useBottomDrawer = {},
|
|
18
|
+
bottomDrawerProps = {},
|
|
19
|
+
watch,
|
|
20
|
+
disabled,
|
|
18
21
|
...props
|
|
19
22
|
}) {
|
|
20
23
|
const shouldUseDrawer = useResponsiveValue(useBottomDrawer)
|
|
21
24
|
const ref = React.useRef(null)
|
|
22
|
-
const { onOpen, onClose, onFastClose, stopDelayedClosing } = useRegisterOverlay({ unmountOnClose })
|
|
25
|
+
const { onOpen, onUpdate, onClose, onFastClose, stopDelayedClosing } = useRegisterOverlay({ unmountOnClose })
|
|
23
26
|
|
|
24
27
|
const click = trigger === 'click'
|
|
25
28
|
const hover = trigger === 'hover'
|
|
@@ -27,13 +30,24 @@ export function Popover({
|
|
|
27
30
|
|
|
28
31
|
renderContent = renderContent || (() => content)
|
|
29
32
|
|
|
30
|
-
const
|
|
31
|
-
|
|
33
|
+
const buildContent = () => (
|
|
34
|
+
<PopoverContent
|
|
35
|
+
placement={placement}
|
|
36
|
+
width={parentWidth ? ref.current?.getBoundingClientRect()?.width : undefined}
|
|
37
|
+
minWidth={parentMinWidth ? ref.current?.getBoundingClientRect()?.width : undefined}
|
|
38
|
+
{...props}
|
|
39
|
+
onMouseEnter={hover ? stopDelayedClosing : undefined}
|
|
40
|
+
onMouseLeave={hover ? onClose : undefined}
|
|
41
|
+
>
|
|
42
|
+
{renderContent({ onClose: onFastClose })}
|
|
43
|
+
</PopoverContent>
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
const computeTriggerRect = () => {
|
|
32
47
|
const rect = ref.current.getBoundingClientRect()
|
|
33
48
|
const scrollX = window.scrollX || window.pageXOffset
|
|
34
49
|
const scrollY = window.scrollY || window.pageYOffset
|
|
35
|
-
|
|
36
|
-
const triggerRect = {
|
|
50
|
+
return {
|
|
37
51
|
left: rect.left + scrollX,
|
|
38
52
|
right: rect.right + scrollX,
|
|
39
53
|
top: rect.top + scrollY,
|
|
@@ -41,20 +55,13 @@ export function Popover({
|
|
|
41
55
|
width: rect.width,
|
|
42
56
|
height: rect.height,
|
|
43
57
|
}
|
|
58
|
+
}
|
|
44
59
|
|
|
60
|
+
const show = (e) => {
|
|
61
|
+
if (e && e.stopPropagation) e.stopPropagation()
|
|
62
|
+
const triggerRect = computeTriggerRect()
|
|
45
63
|
onOpen({
|
|
46
|
-
content: (
|
|
47
|
-
<PopoverContent
|
|
48
|
-
placement={placement}
|
|
49
|
-
width={parentWidth ? rect.width : undefined}
|
|
50
|
-
minWidth={parentMinWidth ? rect.width : undefined}
|
|
51
|
-
{...props}
|
|
52
|
-
onMouseEnter={hover ? stopDelayedClosing : undefined}
|
|
53
|
-
onMouseLeave={hover ? onClose : undefined}
|
|
54
|
-
>
|
|
55
|
-
{renderContent({ onClose: onFastClose })}
|
|
56
|
-
</PopoverContent>
|
|
57
|
-
),
|
|
64
|
+
content: buildContent(),
|
|
58
65
|
triggerRect,
|
|
59
66
|
placement,
|
|
60
67
|
options: { dismissOnClickOutside: click || focus },
|
|
@@ -63,15 +70,31 @@ export function Popover({
|
|
|
63
70
|
|
|
64
71
|
React.useEffect(() => () => onClose(), [])
|
|
65
72
|
|
|
73
|
+
React.useEffect(() => {
|
|
74
|
+
if (!ref.current || !watch) return
|
|
75
|
+
onUpdate({
|
|
76
|
+
content: buildContent(),
|
|
77
|
+
options: { dismissOnClickOutside: click || focus },
|
|
78
|
+
})
|
|
79
|
+
}, watch)
|
|
80
|
+
|
|
66
81
|
if (shouldUseDrawer) {
|
|
67
|
-
return
|
|
82
|
+
return (
|
|
83
|
+
<DrawerPopover
|
|
84
|
+
content={content}
|
|
85
|
+
renderContent={renderContent}
|
|
86
|
+
children={children}
|
|
87
|
+
{...props}
|
|
88
|
+
{...bottomDrawerProps}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
68
91
|
}
|
|
69
92
|
|
|
70
93
|
const child = React.Children.only(children)
|
|
71
94
|
let childProps = { ref, onClick: show }
|
|
72
95
|
|
|
73
|
-
if (hover) childProps = { ref, onMouseEnter: show, onMouseLeave: onClose }
|
|
74
|
-
if (focus) childProps = { ref, onFocus: show }
|
|
96
|
+
if (hover) childProps = { ref, onMouseEnter: show, onMouseLeave: onClose, disabled }
|
|
97
|
+
if (focus) childProps = { ref, onFocus: show, disabled }
|
|
75
98
|
|
|
76
99
|
return React.cloneElement(child, childProps)
|
|
77
100
|
}
|
|
@@ -87,7 +110,7 @@ function DrawerPopover({ children, content, renderContent, snapPoints, ...props
|
|
|
87
110
|
<>
|
|
88
111
|
{React.cloneElement(child, childProps)}
|
|
89
112
|
|
|
90
|
-
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints}>
|
|
113
|
+
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints} {...props}>
|
|
91
114
|
{renderContent({ onClose })}
|
|
92
115
|
</BottomDrawer>
|
|
93
116
|
</>
|
|
@@ -13,6 +13,7 @@ export function Popover({
|
|
|
13
13
|
placement = 'bottom',
|
|
14
14
|
children,
|
|
15
15
|
useBottomDrawer = {},
|
|
16
|
+
bottomDrawerProps = {},
|
|
16
17
|
snapPoints,
|
|
17
18
|
...props
|
|
18
19
|
}) {
|
|
@@ -59,7 +60,7 @@ export function Popover({
|
|
|
59
60
|
<View ref={ref}>
|
|
60
61
|
{children}
|
|
61
62
|
|
|
62
|
-
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints}>
|
|
63
|
+
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints} {...bottomDrawerProps}>
|
|
63
64
|
{renderContent({ onClose: onClose })}
|
|
64
65
|
</BottomDrawer>
|
|
65
66
|
</View>
|
|
@@ -72,7 +73,7 @@ export function Popover({
|
|
|
72
73
|
|
|
73
74
|
{open && (
|
|
74
75
|
<Modal transparent visible={open} animationType="fade" onRequestClose={onClose}>
|
|
75
|
-
<View fullW flex fullH bg="
|
|
76
|
+
<View fullW flex fullH bg="backdrop_op50">
|
|
76
77
|
<TouchableWithoutFeedback onPress={onClose}>
|
|
77
78
|
<View style={{ flex: 1 }}>
|
|
78
79
|
{triggerRect && (
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { BottomDrawer } from '../bottomDrawer'
|
|
4
|
+
import { PopoverContent } from './PopoverContent'
|
|
5
|
+
import { useRegisterOverlay } from '../overlay/OverlayHandler'
|
|
6
|
+
import { useResponsiveValue } from '../../../responsive'
|
|
7
|
+
|
|
8
|
+
export function Popover({
|
|
9
|
+
renderContent,
|
|
10
|
+
content,
|
|
11
|
+
trigger = 'hover',
|
|
12
|
+
placement = 'bottom',
|
|
13
|
+
unmountOnClose,
|
|
14
|
+
children,
|
|
15
|
+
parentWidth,
|
|
16
|
+
parentMinWidth,
|
|
17
|
+
useBottomDrawer = {},
|
|
18
|
+
bottomDrawerProps = {},
|
|
19
|
+
watch,
|
|
20
|
+
...props
|
|
21
|
+
}) {
|
|
22
|
+
const shouldUseDrawer = useResponsiveValue(useBottomDrawer)
|
|
23
|
+
const ref = React.useRef(null)
|
|
24
|
+
const { onOpen, onUpdate, onClose, onFastClose, stopDelayedClosing } = useRegisterOverlay({ unmountOnClose })
|
|
25
|
+
|
|
26
|
+
const click = trigger === 'click'
|
|
27
|
+
const hover = trigger === 'hover'
|
|
28
|
+
const focus = trigger === 'focus'
|
|
29
|
+
|
|
30
|
+
renderContent = renderContent || (() => content)
|
|
31
|
+
|
|
32
|
+
const buildContent = () => (
|
|
33
|
+
<PopoverContent
|
|
34
|
+
placement={placement}
|
|
35
|
+
width={parentWidth ? ref.current?.getBoundingClientRect()?.width : undefined}
|
|
36
|
+
minWidth={parentMinWidth ? ref.current?.getBoundingClientRect()?.width : undefined}
|
|
37
|
+
{...props}
|
|
38
|
+
onMouseEnter={hover ? stopDelayedClosing : undefined}
|
|
39
|
+
onMouseLeave={hover ? onClose : undefined}
|
|
40
|
+
>
|
|
41
|
+
{renderContent({ onClose: onFastClose })}
|
|
42
|
+
</PopoverContent>
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
const computeTriggerRect = () => {
|
|
46
|
+
const rect = ref.current.getBoundingClientRect()
|
|
47
|
+
const scrollX = window.scrollX || window.pageXOffset
|
|
48
|
+
const scrollY = window.scrollY || window.pageYOffset
|
|
49
|
+
return {
|
|
50
|
+
left: rect.left + scrollX,
|
|
51
|
+
right: rect.right + scrollX,
|
|
52
|
+
top: rect.top + scrollY,
|
|
53
|
+
bottom: rect.bottom + scrollY,
|
|
54
|
+
width: rect.width,
|
|
55
|
+
height: rect.height,
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const show = (e) => {
|
|
60
|
+
if (e && e.stopPropagation) e.stopPropagation()
|
|
61
|
+
const triggerRect = computeTriggerRect()
|
|
62
|
+
onOpen({
|
|
63
|
+
content: buildContent(),
|
|
64
|
+
triggerRect,
|
|
65
|
+
placement,
|
|
66
|
+
options: { dismissOnClickOutside: click || focus },
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
React.useEffect(() => () => onClose(), [])
|
|
71
|
+
|
|
72
|
+
// 🔑 re-render do portal quando `watch` (ex.: search) mudar
|
|
73
|
+
React.useEffect(() => {
|
|
74
|
+
if (!ref.current) return
|
|
75
|
+
const triggerRect = computeTriggerRect()
|
|
76
|
+
onUpdate({
|
|
77
|
+
content: buildContent(),
|
|
78
|
+
triggerRect,
|
|
79
|
+
placement,
|
|
80
|
+
options: { dismissOnClickOutside: click || focus },
|
|
81
|
+
})
|
|
82
|
+
}, [watch, renderContent])
|
|
83
|
+
|
|
84
|
+
// const show = (e) => {
|
|
85
|
+
// if (e && e.stopPropagation) e.stopPropagation()
|
|
86
|
+
// const rect = ref.current.getBoundingClientRect()
|
|
87
|
+
// const scrollX = window.scrollX || window.pageXOffset
|
|
88
|
+
// const scrollY = window.scrollY || window.pageYOffset
|
|
89
|
+
|
|
90
|
+
// const triggerRect = {
|
|
91
|
+
// left: rect.left + scrollX,
|
|
92
|
+
// right: rect.right + scrollX,
|
|
93
|
+
// top: rect.top + scrollY,
|
|
94
|
+
// bottom: rect.bottom + scrollY,
|
|
95
|
+
// width: rect.width,
|
|
96
|
+
// height: rect.height,
|
|
97
|
+
// }
|
|
98
|
+
|
|
99
|
+
// onOpen({
|
|
100
|
+
// content: () => (
|
|
101
|
+
// <PopoverContent
|
|
102
|
+
// placement={placement}
|
|
103
|
+
// width={parentWidth ? rect.width : undefined}
|
|
104
|
+
// minWidth={parentMinWidth ? rect.width : undefined}
|
|
105
|
+
// {...props}
|
|
106
|
+
// onMouseEnter={hover ? stopDelayedClosing : undefined}
|
|
107
|
+
// onMouseLeave={hover ? onClose : undefined}
|
|
108
|
+
// >
|
|
109
|
+
// {renderContent({ onClose: onFastClose })}
|
|
110
|
+
// </PopoverContent>
|
|
111
|
+
// ),
|
|
112
|
+
// triggerRect,
|
|
113
|
+
// placement,
|
|
114
|
+
// options: { dismissOnClickOutside: click || focus },
|
|
115
|
+
// })
|
|
116
|
+
// }
|
|
117
|
+
|
|
118
|
+
// React.useEffect(() => () => onClose(), [])
|
|
119
|
+
|
|
120
|
+
if (shouldUseDrawer) {
|
|
121
|
+
return (
|
|
122
|
+
<DrawerPopover
|
|
123
|
+
content={content}
|
|
124
|
+
renderContent={renderContent}
|
|
125
|
+
children={children}
|
|
126
|
+
{...props}
|
|
127
|
+
{...bottomDrawerProps}
|
|
128
|
+
/>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const child = React.Children.only(children)
|
|
133
|
+
let childProps = { ref, onClick: show }
|
|
134
|
+
|
|
135
|
+
if (hover) childProps = { ref, onMouseEnter: show, onMouseLeave: onClose }
|
|
136
|
+
if (focus) childProps = { ref, onFocus: show }
|
|
137
|
+
|
|
138
|
+
return React.cloneElement(child, childProps)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function DrawerPopover({ children, content, renderContent, snapPoints, ...props }) {
|
|
142
|
+
const [open, setOpen] = React.useState(false)
|
|
143
|
+
const onClose = () => setOpen(false)
|
|
144
|
+
|
|
145
|
+
const child = React.Children.only(children)
|
|
146
|
+
let childProps = { onClick: () => setOpen(true) }
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<>
|
|
150
|
+
{React.cloneElement(child, childProps)}
|
|
151
|
+
|
|
152
|
+
<BottomDrawer open={open} onClose={onClose} snapPoints={snapPoints} {...props}>
|
|
153
|
+
{renderContent({ onClose })}
|
|
154
|
+
</BottomDrawer>
|
|
155
|
+
</>
|
|
156
|
+
)
|
|
157
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { AnimatedView } from '../animations'
|
|
4
|
+
import { View } from '../structure'
|
|
5
|
+
import { useTabs } from './TabsHandler'
|
|
6
|
+
|
|
7
|
+
const duration = 100
|
|
8
|
+
|
|
9
|
+
function Item({ item, active, ...props }) {
|
|
10
|
+
const Content = React.useMemo(() => item.renderContent || item.Content, [item.renderContent, item.Content])
|
|
11
|
+
const [open, setOpen] = React.useState(active)
|
|
12
|
+
|
|
13
|
+
React.useEffect(() => {
|
|
14
|
+
if (!!active) {
|
|
15
|
+
setTimeout(() => setOpen(true), duration)
|
|
16
|
+
} else {
|
|
17
|
+
setOpen(active)
|
|
18
|
+
}
|
|
19
|
+
}, [active])
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<AnimatedView open={open} fade={{ duration }} flex display={!open && 'none'} {...props}>
|
|
23
|
+
<Content />
|
|
24
|
+
</AnimatedView>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function ActiveTabContent({ lazy, unmountOnClose }) {
|
|
29
|
+
const { activeKey, items } = useTabs()
|
|
30
|
+
if (!items?.length) return false
|
|
31
|
+
|
|
32
|
+
return items.map((item) => (
|
|
33
|
+
<Item key={item.key} item={item} active={item.key === activeKey} lazy={lazy} unmountOnClose={unmountOnClose} />
|
|
34
|
+
))
|
|
35
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
const TabsContext = React.createContext(null)
|
|
4
|
+
export const useTabs = () => React.useContext(TabsContext) || {}
|
|
5
|
+
|
|
6
|
+
export function TabsHandler({ children, items, initialKey }) {
|
|
7
|
+
const [activeKey, setActiveKey] = React.useState(initialKey || items?.[0]?.key)
|
|
8
|
+
|
|
9
|
+
const activeTab = React.useMemo(() => {
|
|
10
|
+
return items?.find((item) => item.key === activeKey)
|
|
11
|
+
}, [activeKey])
|
|
12
|
+
|
|
13
|
+
const value = { items, onChange: setActiveKey, activeKey, activeTab }
|
|
14
|
+
|
|
15
|
+
return <TabsContext.Provider value={value}>{children}</TabsContext.Provider>
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Menu } from '../actions'
|
|
2
|
+
import { SegmentedPicker } from '../inputs'
|
|
3
|
+
import { useTabs } from './TabsHandler'
|
|
4
|
+
|
|
5
|
+
export function TabsMenu(props) {
|
|
6
|
+
const { activeKey, items, onChange } = useTabs()
|
|
7
|
+
|
|
8
|
+
return <Menu items={items} activeKey={activeKey} onChange={({ key }) => onChange(key)} {...props} />
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function TabsSegmentedMenu(props) {
|
|
12
|
+
const { activeKey, items, onChange } = useTabs()
|
|
13
|
+
|
|
14
|
+
return <SegmentedPicker options={items} valueKey="key" value={activeKey} onChange={onChange} {...props} />
|
|
15
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { mapObjIndexed, mergeDeepRight, values, pipe, filter } from 'ramda'
|
|
2
|
+
|
|
3
|
+
import { DEFAULT_THEMES, useThemeHandler } from '../../theme'
|
|
4
|
+
import { IconLabel } from '../presentation'
|
|
5
|
+
import { Link } from '../actions'
|
|
6
|
+
import { Picker } from '../inputs'
|
|
7
|
+
import { ThemeThumb } from './ThemeThumb'
|
|
8
|
+
|
|
9
|
+
export function ThemePicker({ onChange, onlyKeys, hideKeys }) {
|
|
10
|
+
const { activeThemeKey, setActiveThemeKey, themes, onChangeTheme } = useThemeHandler()
|
|
11
|
+
|
|
12
|
+
let options = pipe(
|
|
13
|
+
mergeDeepRight(DEFAULT_THEMES),
|
|
14
|
+
mapObjIndexed((obj, key) => ({ ...obj, value: key, key })),
|
|
15
|
+
values,
|
|
16
|
+
filter((item) => {
|
|
17
|
+
if (item.value === '_all') return false
|
|
18
|
+
if (onlyKeys && onlyKeys.includes(item.value)) return true
|
|
19
|
+
if (hideKeys && hideKeys.includes(item.value)) return false
|
|
20
|
+
return true
|
|
21
|
+
})
|
|
22
|
+
)(themes)
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Picker
|
|
26
|
+
colSpan={12}
|
|
27
|
+
gap="lg"
|
|
28
|
+
value={activeThemeKey}
|
|
29
|
+
onChange={(key) => {
|
|
30
|
+
setActiveThemeKey(key)
|
|
31
|
+
onChangeTheme?.(key)
|
|
32
|
+
onChange?.(key)
|
|
33
|
+
}}
|
|
34
|
+
options={options}
|
|
35
|
+
renderOption={({ option, selected, onChange }) => (
|
|
36
|
+
<Link onPress={onChange} gap="xs">
|
|
37
|
+
<ThemeThumb value={option.value} />
|
|
38
|
+
<IconLabel
|
|
39
|
+
center
|
|
40
|
+
label={option.label}
|
|
41
|
+
icon={selected && 'checkbox-circle-fill'}
|
|
42
|
+
color={selected ? 'primary' : 'text3'}
|
|
43
|
+
strong
|
|
44
|
+
/>
|
|
45
|
+
</Link>
|
|
46
|
+
)}
|
|
47
|
+
/>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BottomDrawer } from '../structure'
|
|
2
|
+
import { ScrollView } from '../list/ScrollView'
|
|
3
|
+
import { ThemePicker } from './ThemePicker'
|
|
4
|
+
|
|
5
|
+
export function ThemePickerDrawer({ open, onClose, onChange }) {
|
|
6
|
+
return (
|
|
7
|
+
<BottomDrawer open={open} onClose={onClose} maxWidth={550} snapPoints={['50%', '85%']}>
|
|
8
|
+
<ScrollView padding="md">
|
|
9
|
+
<ThemePicker onChange={onChange} />
|
|
10
|
+
</ScrollView>
|
|
11
|
+
</BottomDrawer>
|
|
12
|
+
)
|
|
13
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { View } from '../structure'
|
|
2
|
+
import { useFormattedTheme } from '../../theme/format/formatTheme'
|
|
3
|
+
import { useResponsiveValue } from '../../responsive'
|
|
4
|
+
import { useThemeHandler } from '../../theme'
|
|
5
|
+
|
|
6
|
+
export function ThemeThumb({ value }) {
|
|
7
|
+
const { themes } = useThemeHandler()
|
|
8
|
+
const { colors, label } = useFormattedTheme(themes, value)
|
|
9
|
+
const isMobile = useResponsiveValue({ smd: true, df: false })
|
|
10
|
+
|
|
11
|
+
if (isMobile) {
|
|
12
|
+
return (
|
|
13
|
+
<View centerH>
|
|
14
|
+
<View
|
|
15
|
+
bg={colors.mainBG}
|
|
16
|
+
height={175}
|
|
17
|
+
fullW
|
|
18
|
+
br="md"
|
|
19
|
+
hiddenOverflow
|
|
20
|
+
border={2}
|
|
21
|
+
brColor={colors.divider}
|
|
22
|
+
maxWidth={100}
|
|
23
|
+
>
|
|
24
|
+
<View bg={colors.overlayBG} height={25} padding={8} row borderB brColor={colors.divider}>
|
|
25
|
+
<View width={25} fullH bg={colors.primary} br="xxs" />
|
|
26
|
+
<View flex />
|
|
27
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
28
|
+
</View>
|
|
29
|
+
|
|
30
|
+
<View flex padding={6}>
|
|
31
|
+
<View br="md" bg={colors.overlayBG} flex gap={8} padding={8} border brColor={colors.divider}>
|
|
32
|
+
<View bg={colors.text2} height={4} br="xxs" />
|
|
33
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
34
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
35
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
36
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
37
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
38
|
+
|
|
39
|
+
<View flex />
|
|
40
|
+
|
|
41
|
+
<View height={6} fullW bg={colors.primary} br="xxs" />
|
|
42
|
+
</View>
|
|
43
|
+
</View>
|
|
44
|
+
|
|
45
|
+
<View
|
|
46
|
+
bg={colors.overlayBG}
|
|
47
|
+
height={25}
|
|
48
|
+
padding={8}
|
|
49
|
+
row
|
|
50
|
+
borderT
|
|
51
|
+
brColor={colors.divider}
|
|
52
|
+
justify="space-around"
|
|
53
|
+
centerV
|
|
54
|
+
>
|
|
55
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
56
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
57
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
58
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
59
|
+
<View ratio={1} fullH bg={colors.divider} round />
|
|
60
|
+
</View>
|
|
61
|
+
</View>
|
|
62
|
+
</View>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<View bg={colors.mainBG} height={175} fullW br="md" hiddenOverflow border={2} brColor={colors.divider}>
|
|
68
|
+
<View bg={colors.overlayBG} height={25} paddingV={8} paddingH={12} row borderB brColor={colors.divider}>
|
|
69
|
+
<View width={25} bg={colors.primary} br="xxs" />
|
|
70
|
+
<View flex />
|
|
71
|
+
<View ratio={1} fullH bg={colors.text4} round />
|
|
72
|
+
</View>
|
|
73
|
+
|
|
74
|
+
<View row padding={12} paddingT={8} gap={6} flex>
|
|
75
|
+
<View br="xs" bg={colors.overlayBG} flex gap={6} padding={7} border brColor={colors.divider}>
|
|
76
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
77
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
78
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
79
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
80
|
+
<View bg={colors.text4} height={2} br="xxs" />
|
|
81
|
+
</View>
|
|
82
|
+
<View br="xs" bg={colors.overlayBG} flex={4} gap={8} padding={7} border brColor={colors.divider}>
|
|
83
|
+
<View bg={colors.text2} height={4} br="xxs" width={30} />
|
|
84
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
85
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
86
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
87
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
88
|
+
<View bg={colors.text4} height={2} br="xxs" width={'80%'} />
|
|
89
|
+
<View flex />
|
|
90
|
+
<View row toRight gap={6}>
|
|
91
|
+
<View width={25} height={8} bg={colors.text4} br="xxs" />
|
|
92
|
+
<View width={25} height={8} bg={colors.primary} br="xxs" />
|
|
93
|
+
</View>
|
|
94
|
+
</View>
|
|
95
|
+
</View>
|
|
96
|
+
</View>
|
|
97
|
+
)
|
|
98
|
+
}
|
package/src/helpers/index.js
CHANGED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import { AbsStorage } from '../abstractions/helpers/storage'
|
|
4
|
+
|
|
5
|
+
function set(key, value) {
|
|
6
|
+
return AbsStorage.set(key, JSON.stringify(value))
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function setAsync(key, value) {
|
|
10
|
+
return AbsStorage.setAsync(key, JSON.stringify(value))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function get(key) {
|
|
14
|
+
const value = AbsStorage.get(key)
|
|
15
|
+
return formatStoragedValue(value)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function getAsync(key) {
|
|
19
|
+
return AbsStorage.setAsync(key).then((value) => {
|
|
20
|
+
return formatStoragedValue(value)
|
|
21
|
+
})
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function formatStoragedValue(value) {
|
|
25
|
+
try {
|
|
26
|
+
if (!value) return value
|
|
27
|
+
value = JSON.parse(value)
|
|
28
|
+
if (value === 'undefined') return undefined
|
|
29
|
+
if (value === 'null') return undefined
|
|
30
|
+
return value
|
|
31
|
+
} catch (e) {
|
|
32
|
+
return value
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function useState(key, defaultValue) {
|
|
37
|
+
const [value, setValue] = React.useState(get(key) || defaultValue)
|
|
38
|
+
|
|
39
|
+
const handleChange = (newValue) => {
|
|
40
|
+
set(key, newValue)
|
|
41
|
+
setValue(newValue)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return [value, handleChange]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const Storage = {
|
|
48
|
+
...AbsStorage,
|
|
49
|
+
set,
|
|
50
|
+
setAsync,
|
|
51
|
+
get,
|
|
52
|
+
getAsync,
|
|
53
|
+
useState,
|
|
54
|
+
}
|
package/src/helpers/string.js
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
adjust,
|
|
3
|
+
compose,
|
|
4
|
+
defaultTo,
|
|
5
|
+
head,
|
|
6
|
+
join,
|
|
7
|
+
juxt,
|
|
8
|
+
map,
|
|
9
|
+
pipe,
|
|
10
|
+
replace,
|
|
11
|
+
split,
|
|
12
|
+
tail,
|
|
13
|
+
toLower,
|
|
14
|
+
toUpper,
|
|
15
|
+
trim,
|
|
16
|
+
} from 'ramda'
|
|
2
17
|
|
|
3
18
|
export const removeSpecialChars = replace(/[^a-zA-Z ,0-9]/g, '')
|
|
4
19
|
|
|
@@ -55,3 +70,5 @@ export const truncate = truncateString
|
|
|
55
70
|
export const slugify = (text) => {
|
|
56
71
|
return toSnakeCase(text)
|
|
57
72
|
}
|
|
73
|
+
|
|
74
|
+
export const normalizeString = pipe(toLower, trim, (str) => str.normalize('NFD').replace(/[\u0300-\u036f]/g, ''))
|