@neko-os/ui 0.0.12 → 0.1.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 (143) hide show
  1. package/dist/abstractions/KeyboardAvoidingView.js +1 -0
  2. package/dist/abstractions/KeyboardAvoidingView.native.js +1 -0
  3. package/dist/components/actions/ActionsDrawer.js +1 -0
  4. package/dist/components/actions/Button.js +1 -1
  5. package/dist/components/actions/Dropdown.js +1 -1
  6. package/dist/components/actions/FloatingMenu.js +1 -0
  7. package/dist/components/actions/index.js +1 -1
  8. package/dist/components/actions/menu/VerticalMenu.js +1 -1
  9. package/dist/components/animations/AnimatedTopBar.js +1 -0
  10. package/dist/components/animations/AnimatedTopBar.native.js +1 -0
  11. package/dist/components/animations/AnimatedTopBar.web.js +1 -0
  12. package/dist/components/animations/ParallaxHeader.js +1 -0
  13. package/dist/components/animations/ParallaxHeader.native.js +1 -0
  14. package/dist/components/animations/ParallaxHeader.web.js +1 -0
  15. package/dist/components/animations/ReanimatedScrollHandler.js +1 -0
  16. package/dist/components/animations/ReanimatedScrollHandler.native.js +1 -0
  17. package/dist/components/animations/ReanimatedScrollHandler.web.js +1 -0
  18. package/dist/components/animations/index.js +1 -1
  19. package/dist/components/form/FormItem.js +1 -1
  20. package/dist/components/form/FormList.js +1 -1
  21. package/dist/components/form/SubmitButton.js +1 -1
  22. package/dist/components/form/index.js +1 -1
  23. package/dist/components/form/useNewForm.js +1 -1
  24. package/dist/components/form/validation/defaultMessages.js +1 -0
  25. package/dist/components/form/validation/index.js +1 -0
  26. package/dist/components/form/validation/normalizeRules.js +1 -0
  27. package/dist/components/form/validation/shouldValidateOn.js +1 -0
  28. package/dist/components/form/validation/validateRules.js +1 -0
  29. package/dist/components/form/validation/validators.js +1 -0
  30. package/dist/components/index.js +1 -1
  31. package/dist/components/inputs/InputWrapper.js +1 -1
  32. package/dist/components/inputs/NumberInput.js +1 -1
  33. package/dist/components/inputs/Picker.js +1 -1
  34. package/dist/components/inputs/Select.js +1 -1
  35. package/dist/components/presentation/Avatar.js +1 -1
  36. package/dist/components/presentation/AvatarLabel.js +1 -1
  37. package/dist/components/presentation/LabelValue.js +1 -1
  38. package/dist/components/presentation/Result.js +1 -1
  39. package/dist/components/presentation/Tooltip.js +1 -1
  40. package/dist/components/sections/Section.js +1 -0
  41. package/dist/components/sections/SectionItem.js +1 -0
  42. package/dist/components/sections/SectionItemLink.js +1 -0
  43. package/dist/components/sections/index.js +1 -0
  44. package/dist/components/state/StatePresenter.js +1 -0
  45. package/dist/components/state/index.js +1 -1
  46. package/dist/components/structure/BlurView.js +1 -1
  47. package/dist/components/structure/KeyboardAvoidingView.js +1 -0
  48. package/dist/components/structure/TopBar.js +1 -0
  49. package/dist/components/structure/bottomDrawer/index.js +1 -1
  50. package/dist/components/structure/bottomDrawer/index.native.js +1 -1
  51. package/dist/components/structure/bottomDrawer/index.web.js +1 -1
  52. package/dist/components/structure/bottomDrawer/native/BottomDrawer.js +1 -1
  53. package/dist/components/structure/bottomDrawer/native/DrawerScrollView.js +1 -1
  54. package/dist/components/structure/bottomDrawer/native/createDrawerScrollComponent.js +1 -0
  55. package/dist/components/structure/drawer/Drawer.web.js +1 -0
  56. package/dist/components/structure/index.js +1 -1
  57. package/dist/components/text/DateText.js +1 -0
  58. package/dist/components/text/index.js +1 -1
  59. package/dist/components/theme/ThemePicker.js +1 -1
  60. package/dist/helpers/index.js +1 -1
  61. package/dist/helpers/storage.js +1 -1
  62. package/dist/responsive/responsiveHooks.js +1 -1
  63. package/dist/theme/ThemeHandler.js +1 -1
  64. package/dist/theme/default/base.js +1 -1
  65. package/dist/theme/default/blackTheme.js +1 -1
  66. package/dist/theme/default/cyberpunkTheme.js +1 -1
  67. package/dist/theme/default/darkTheme.js +1 -1
  68. package/dist/theme/default/hackerTheme.js +1 -1
  69. package/dist/theme/default/lightTheme.js +1 -1
  70. package/dist/theme/default/msdosTheme.js +1 -1
  71. package/dist/theme/default/paperTheme.js +1 -1
  72. package/package.json +1 -1
  73. package/src/abstractions/KeyboardAvoidingView.js +3 -0
  74. package/src/abstractions/KeyboardAvoidingView.native.js +3 -0
  75. package/src/components/actions/ActionsDrawer.js +68 -0
  76. package/src/components/actions/Button.js +2 -1
  77. package/src/components/actions/Dropdown.js +11 -8
  78. package/src/components/actions/FloatingMenu.js +39 -0
  79. package/src/components/actions/index.js +2 -0
  80. package/src/components/actions/menu/VerticalMenu.js +1 -2
  81. package/src/components/animations/AnimatedTopBar.js +10 -0
  82. package/src/components/animations/AnimatedTopBar.native.js +34 -0
  83. package/src/components/animations/AnimatedTopBar.web.js +1 -0
  84. package/src/components/animations/ParallaxHeader.js +9 -0
  85. package/src/components/animations/ParallaxHeader.native.js +32 -0
  86. package/src/components/animations/ParallaxHeader.web.js +32 -0
  87. package/src/components/animations/ReanimatedScrollHandler.js +8 -0
  88. package/src/components/animations/ReanimatedScrollHandler.native.js +24 -0
  89. package/src/components/animations/ReanimatedScrollHandler.web.js +1 -0
  90. package/src/components/animations/index.js +3 -0
  91. package/src/components/form/FormItem.js +42 -5
  92. package/src/components/form/FormList.js +23 -4
  93. package/src/components/form/SubmitButton.js +4 -2
  94. package/src/components/form/index.js +1 -0
  95. package/src/components/form/useNewForm.js +108 -15
  96. package/src/components/form/validation/defaultMessages.js +20 -0
  97. package/src/components/form/validation/index.js +5 -0
  98. package/src/components/form/validation/normalizeRules.js +22 -0
  99. package/src/components/form/validation/shouldValidateOn.js +21 -0
  100. package/src/components/form/validation/validateRules.js +83 -0
  101. package/src/components/form/validation/validators.js +82 -0
  102. package/src/components/index.js +1 -0
  103. package/src/components/inputs/InputWrapper.js +1 -1
  104. package/src/components/inputs/NumberInput.js +6 -5
  105. package/src/components/inputs/Picker.js +3 -2
  106. package/src/components/inputs/Select.js +31 -15
  107. package/src/components/presentation/Avatar.js +2 -2
  108. package/src/components/presentation/AvatarLabel.js +2 -0
  109. package/src/components/presentation/LabelValue.js +7 -5
  110. package/src/components/presentation/Result.js +2 -2
  111. package/src/components/presentation/Tooltip.js +1 -1
  112. package/src/components/sections/Section.js +50 -0
  113. package/src/components/sections/SectionItem.js +24 -0
  114. package/src/components/sections/SectionItemLink.js +33 -0
  115. package/src/components/sections/index.js +3 -0
  116. package/src/components/state/StatePresenter.js +41 -0
  117. package/src/components/state/index.js +1 -0
  118. package/src/components/structure/BlurView.js +1 -0
  119. package/src/components/structure/KeyboardAvoidingView.js +52 -0
  120. package/src/components/structure/TopBar.js +45 -0
  121. package/src/components/structure/bottomDrawer/index.js +2 -0
  122. package/src/components/structure/bottomDrawer/index.native.js +2 -1
  123. package/src/components/structure/bottomDrawer/index.web.js +2 -1
  124. package/src/components/structure/bottomDrawer/native/BottomDrawer.js +14 -20
  125. package/src/components/structure/bottomDrawer/native/DrawerScrollView.js +4 -82
  126. package/src/components/structure/bottomDrawer/native/createDrawerScrollComponent.js +131 -0
  127. package/src/components/structure/drawer/Drawer.web.js +3 -0
  128. package/src/components/structure/index.js +2 -0
  129. package/src/components/text/DateText.js +11 -0
  130. package/src/components/text/index.js +1 -0
  131. package/src/components/theme/ThemePicker.js +1 -2
  132. package/src/helpers/index.js +1 -0
  133. package/src/helpers/storage.js +32 -9
  134. package/src/responsive/responsiveHooks.js +6 -0
  135. package/src/theme/ThemeHandler.js +6 -3
  136. package/src/theme/default/base.js +16 -4
  137. package/src/theme/default/blackTheme.js +1 -0
  138. package/src/theme/default/cyberpunkTheme.js +10 -0
  139. package/src/theme/default/darkTheme.js +1 -0
  140. package/src/theme/default/hackerTheme.js +17 -3
  141. package/src/theme/default/lightTheme.js +1 -0
  142. package/src/theme/default/msdosTheme.js +9 -10
  143. package/src/theme/default/paperTheme.js +10 -0
@@ -1,3 +1,4 @@
1
+ import { dissoc } from 'ramda'
1
2
  import React from 'react'
2
3
 
3
4
  import { Icon, IconLabel } from '../presentation'
@@ -38,6 +39,7 @@ export function Select({
38
39
  pickerProps,
39
40
  popoverProps,
40
41
  popoverMaxHeight,
42
+ snapPoints,
41
43
  ...props
42
44
  }) {
43
45
  const [focus, setFocus] = React.useState(false)
@@ -52,7 +54,17 @@ export function Select({
52
54
  onEndReached = onEndReached || pickerProps?.onEndReached
53
55
  renderFooter = renderFooter || pickerProps?.renderFooter
54
56
  renderHeader = renderHeader || pickerProps?.renderHeader
55
- pickerProps = { ...pickerProps, labelKey, valueKey, useRawOption, multiple, onEndReached, renderFooter, renderHeader }
57
+ pickerProps = {
58
+ ...pickerProps,
59
+
60
+ labelKey,
61
+ valueKey,
62
+ useRawOption,
63
+ multiple,
64
+ onEndReached,
65
+ renderFooter,
66
+ renderHeader,
67
+ }
56
68
 
57
69
  popoverMaxHeight = popoverMaxHeight || 300
58
70
 
@@ -93,7 +105,10 @@ export function Select({
93
105
  const finalRenderOption = React.useCallback(
94
106
  (params) => {
95
107
  if (!!renderOption) return renderOption(params)
96
- const { option, labelKey, selected } = params
108
+ let { option, labelKey, selected } = params
109
+ if (option?.id) option = dissoc('id', option)
110
+ if (option?.color) option = { ...option, color: undefined, iconColor: option.color }
111
+
97
112
  return <IconLabel {...option} label={option?.[labelKey]} flex strong={selected} />
98
113
  },
99
114
  [renderOption]
@@ -103,7 +118,7 @@ export function Select({
103
118
  <Popover
104
119
  trigger="click"
105
120
  placement={placement || 'bottomLeft'}
106
- snapPoints={[450]}
121
+ snapPoints={snapPoints || [450]}
107
122
  useBottomDrawer={useBottomDrawer}
108
123
  parentWidth
109
124
  padding={0}
@@ -112,17 +127,6 @@ export function Select({
112
127
  maxHeight={popoverMaxHeight}
113
128
  {...popoverProps}
114
129
  renderContent={({ onClose }) => (
115
- <>
116
- {useBottomDrawer && useSearch && (
117
- <View padding="md" paddingB="xs">
118
- <TextInput
119
- prefixIcon="search-line"
120
- prefixIconColor="text4"
121
- value={search}
122
- onChange={handleChangeSearch}
123
- />
124
- </View>
125
- )}
126
130
  <Picker
127
131
  row={false}
128
132
  options={searchOptions(options, search, { labelKey })}
@@ -137,6 +141,19 @@ export function Select({
137
141
  if (!multiple) onClose()
138
142
  }}
139
143
  {...pickerProps}
144
+ renderHeader={useBottomDrawer && useSearch ? () => (
145
+ <>
146
+ <View padding="md" paddingB="xs">
147
+ <TextInput
148
+ prefixIcon="search-line"
149
+ prefixIconColor="text4"
150
+ value={search}
151
+ onChange={handleChangeSearch}
152
+ />
153
+ </View>
154
+ {renderHeader?.()}
155
+ </>
156
+ ) : renderHeader}
140
157
  renderOption={({ option, selected, onChange }) => (
141
158
  <Link
142
159
  row
@@ -156,7 +173,6 @@ export function Select({
156
173
  </Link>
157
174
  )}
158
175
  />
159
- </>
160
176
  )}
161
177
  >
162
178
  <Input
@@ -54,7 +54,7 @@ export function Avatar(rootProps) {
54
54
  useOverflowModifier
55
55
  )([{}, rootProps])
56
56
 
57
- let { initials, name, icon, src, invert, textProps, iconProps, ...props } = formattedProps
57
+ let { initials, name, icon, src, invert, textProps, iconProps, iconSize, ...props } = formattedProps
58
58
  initials = initials || getInitials(name)
59
59
 
60
60
  let content = (
@@ -66,7 +66,7 @@ export function Avatar(rootProps) {
66
66
  icon={icon}
67
67
  invert={invert}
68
68
  textProps={{ strong: true, ...textProps }}
69
- iconProps={iconProps}
69
+ iconProps={{ size: iconSize, ...iconProps }}
70
70
  />
71
71
  )
72
72
  if (!!src) content = <Image br={0} src={src} width={sizeCode} height={sizeCode} />
@@ -26,6 +26,7 @@ export function AvatarLabel(rootProps) {
26
26
  avatarProps,
27
27
  moveAvatarSizeScale,
28
28
  avatarSize,
29
+ iconSize,
29
30
  ...props
30
31
  } = formattedProps
31
32
  const hasAvatar = !!name || !!initials || !!src
@@ -47,6 +48,7 @@ export function AvatarLabel(rootProps) {
47
48
  dynamicColor={dynamicColor}
48
49
  square={square}
49
50
  marginH={2}
51
+ iconSize={iconSize}
50
52
  {...avatarProps}
51
53
  />
52
54
  }
@@ -4,11 +4,12 @@ import { IconLabel } from './IconLabel'
4
4
  import { Text } from '../text/Text'
5
5
  import { View } from '../structure/View'
6
6
  import { moveScale } from '../../theme/helpers/sizeScale'
7
+ import { useColorConverter } from '../../modifiers/colorConverter'
7
8
  import { useDefaultModifier } from '../../modifiers/default'
8
9
  import { useSizeConverter } from '../../modifiers/sizeConverter'
9
10
  import { useThemeComponentModifier } from '../../modifiers/themeComponent'
10
11
 
11
- const DEFAULT_PROPS = ([{ sizeCode }, { vertical, spread }]) => {
12
+ const DEFAULT_PROPS = ([{ sizeCode, color }, { vertical, spread }]) => {
12
13
  return {
13
14
  row: !vertical,
14
15
  centerV: !vertical,
@@ -17,7 +18,7 @@ const DEFAULT_PROPS = ([{ sizeCode }, { vertical, spread }]) => {
17
18
  labelProps: {
18
19
  size: moveScale(sizeCode, !vertical ? 0 : -2),
19
20
  moveIconSizeScale: !vertical ? -1 : -2,
20
- color: 'text3',
21
+ color: color || 'text3',
21
22
  },
22
23
  valueProps: {
23
24
  size: sizeCode,
@@ -28,17 +29,18 @@ const DEFAULT_PROPS = ([{ sizeCode }, { vertical, spread }]) => {
28
29
 
29
30
  export function LabelValue({ children, ...rootProps }) {
30
31
  const [{ sizeCode, color }, formattedProps] = pipe(
31
- // useColorConverter(),
32
+ useColorConverter(),
32
33
  useSizeConverter('elementHeights', 'md'),
33
34
  useThemeComponentModifier('Labelvalue'), //
34
35
  useDefaultModifier(DEFAULT_PROPS)
35
36
  )([{}, rootProps])
36
37
 
37
- const { icon, label, iconColor, labelProps, value, valueProps, vertical, spread, ...props } = formattedProps
38
+ const { icon, label, iconColor, labelProps, value, valueColor, valueProps, vertical, spread, ...props } =
39
+ formattedProps
38
40
  let separator = !vertical && !spread ? ':' : ''
39
41
 
40
42
  let content = children || value
41
- if (is(String, value)) content = <Text label={value} {...valueProps} />
43
+ if (is(String, value)) content = <Text label={value} color={valueColor || color} {...valueProps} />
42
44
 
43
45
  return (
44
46
  <View className="neko-label-value" {...props}>
@@ -46,11 +46,11 @@ export function Result({
46
46
  <View className="neko-result" center padding="lg" {...props}>
47
47
  {!!icon && <Icon name={icon} color={iconColor} size={42} primary {...iconProps} />}
48
48
  {!!icon && <Divider height={10} />}
49
- <Text h4 {...textProps} {...titleProps}>
49
+ <Text h4 center {...textProps} {...titleProps}>
50
50
  {title}
51
51
  </Text>
52
52
  {!!description && (
53
- <Text text3 sm marginT="sm" {...textProps} {...descriptionProps}>
53
+ <Text text3 sm marginT="sm" center {...textProps} {...descriptionProps}>
54
54
  {description}
55
55
  </Text>
56
56
  )}
@@ -10,7 +10,7 @@ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
10
10
  export function Tooltip(rootProps) {
11
11
  const [{ loading, fontColor, sizeCode }, formattedProps] = pipe(
12
12
  useColorConverter('overlayBG'),
13
- useSizeConverter('text', 'md'),
13
+ useSizeConverter('text', 'sm'),
14
14
  useThemeComponentModifier('Tooltip'),
15
15
  useFullColorModifier
16
16
  )([{}, rootProps])
@@ -0,0 +1,50 @@
1
+ import { pipe } from 'ramda'
2
+ import React from 'react'
3
+
4
+ import { Divider } from '../helpers/Separator'
5
+ import { Text } from '../text'
6
+ import { View } from '../structure'
7
+ import { useDefaultModifier } from '../../modifiers/default'
8
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
9
+
10
+ const DEFAULT_PROPS = {
11
+ marginH: 'md',
12
+ bg: 'overlayBG',
13
+ br: 'md',
14
+ titleProps: {
15
+ strong: true,
16
+ text4: true,
17
+ sm: true,
18
+ marginB: 'sm',
19
+ paddingH: 'md',
20
+ },
21
+ dividerProps: {
22
+ line: true,
23
+ height: 1,
24
+ },
25
+ }
26
+
27
+ export function Section({ children, title, ...rootProps }) {
28
+ const [{}, formattedProps] = pipe(
29
+ useThemeComponentModifier('Section'), //
30
+ useDefaultModifier(DEFAULT_PROPS)
31
+ )([{}, rootProps])
32
+
33
+ const { titleProps, dividerProps, ...props } = formattedProps
34
+
35
+ const childArray = React.Children.toArray(children)
36
+
37
+ return (
38
+ <View>
39
+ {!!title && <Text marginH={props.marginH} {...titleProps} label={title} />}
40
+ <View className="neko-section" {...props}>
41
+ {childArray.map((child, i) => (
42
+ <React.Fragment key={child.key}>
43
+ {child}
44
+ {i < childArray.length - 1 && <Divider {...dividerProps} />}
45
+ </React.Fragment>
46
+ ))}
47
+ </View>
48
+ </View>
49
+ )
50
+ }
@@ -0,0 +1,24 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { LabelValue } from '../presentation'
4
+ import { useColorConverter } from '../../modifiers/colorConverter'
5
+ import { useDefaultModifier } from '../../modifiers/default'
6
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
7
+
8
+ const DEFAULT_PROPS = {
9
+ paddingH: 'md',
10
+ paddingV: 'sm',
11
+ minH: 'md',
12
+ }
13
+
14
+ export function SectionItem({ ...rootProps }) {
15
+ const [{ color }, formattedProps] = pipe(
16
+ useColorConverter(),
17
+ useThemeComponentModifier('SectionItem'), //
18
+ useDefaultModifier(DEFAULT_PROPS)
19
+ )([{}, rootProps])
20
+
21
+ const { ...props } = formattedProps
22
+
23
+ return <LabelValue spread className="neko-section-item" color={color} {...props} />
24
+ }
@@ -0,0 +1,33 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { IconLabel } from '../presentation'
4
+ import { Link } from '../actions'
5
+ import { SectionItem } from './SectionItem'
6
+ import { useColorConverter } from '../../modifiers/colorConverter'
7
+ import { useDefaultModifier } from '../../modifiers/default'
8
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
9
+
10
+ const DEFAULT_PROPS = {
11
+ icon: 'md',
12
+ paddingV: 'sm',
13
+ minH: 'md',
14
+ icon: 'arrow-right-s-line',
15
+ }
16
+
17
+ export function SectionItemLink({ children, value, onPress, ...rootProps }) {
18
+ const [{ color }, formattedProps] = pipe(
19
+ useColorConverter(),
20
+ useThemeComponentModifier('SectionItemLink'), //
21
+ useDefaultModifier(DEFAULT_PROPS)
22
+ )([{}, rootProps])
23
+
24
+ const { icon, iconLabelProps, ...props } = formattedProps
25
+
26
+ return (
27
+ <Link className="neko-section-item-link" onPress={onPress}>
28
+ <SectionItem color={color} {...props}>
29
+ {children || <IconLabel gap={2} invert color={color} {...iconLabelProps} label={value} icon={icon} />}
30
+ </SectionItem>
31
+ </Link>
32
+ )
33
+ }
@@ -0,0 +1,3 @@
1
+ export * from './Section'
2
+ export * from './SectionItem'
3
+ export * from './SectionItemLink'
@@ -0,0 +1,41 @@
1
+ import { Loading } from './Loading'
2
+ import { Result } from '../presentation'
3
+ import { View } from '../structure'
4
+
5
+ export function StatePresenter({
6
+ loading,
7
+ error,
8
+ empty,
9
+ errorTitle = 'Something went wrong',
10
+ errorDescription,
11
+ emptyTitle = 'No results',
12
+ emptyDescription,
13
+ children,
14
+ ...props
15
+ }) {
16
+ if (loading) {
17
+ return (
18
+ <View flex center {...props}>
19
+ <Loading />
20
+ </View>
21
+ )
22
+ }
23
+
24
+ if (error) {
25
+ return (
26
+ <View flex center {...props}>
27
+ <Result type="error" title={errorTitle} description={errorDescription || error.message} />
28
+ </View>
29
+ )
30
+ }
31
+
32
+ if (empty) {
33
+ return (
34
+ <View flex center {...props}>
35
+ <Result type="empty" title={emptyTitle} description={emptyDescription} />
36
+ </View>
37
+ )
38
+ }
39
+
40
+ return children
41
+ }
@@ -1,2 +1,3 @@
1
1
  export * from './Loading'
2
2
  export * from './LoadingView'
3
+ export * from './StatePresenter'
@@ -25,6 +25,7 @@ const DEFAULT_PROPS =
25
25
  const isDark = tinycolor(colors?.overlayBG || colors?.bg).isDark()
26
26
 
27
27
  return {
28
+ width: 'auto',
28
29
  tint: isDark ? 'dark' : 'light',
29
30
  }
30
31
  }
@@ -0,0 +1,52 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { AbsKeyboardAvoidingView } from '../../abstractions/KeyboardAvoidingView'
4
+ import { Platform } from '../../abstractions/Platform'
5
+ import { useSafeAreaInsets } from '../../abstractions/helpers/useSafeAreaInsets'
6
+ import { useAnimationModifier } from '../../modifiers/animation'
7
+ import { useBackgroundModifier } from '../../modifiers/background'
8
+ import { useBorderModifier } from '../../modifiers/border'
9
+ import { useCursorModifier } from '../../modifiers/cursor'
10
+ import { useDisplayModifier } from '../../modifiers/display'
11
+ import { useFlexModifier } from '../../modifiers/flex'
12
+ import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
13
+ import { useMarginModifier } from '../../modifiers/margin'
14
+ import { useOverflowModifier } from '../../modifiers/overflow'
15
+ import { usePaddingModifier } from '../../modifiers/padding'
16
+ import { usePositionModifier } from '../../modifiers/position'
17
+ import { useShadowModifier } from '../../modifiers/shadow'
18
+ import { useSizeModifier } from '../../modifiers/size'
19
+ import { useStateModifier } from '../../modifiers/state'
20
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
21
+
22
+ export function KeyboardAvoidingView({ children, keyboardVerticalOffset = 0, ...rootProps }) {
23
+ const { bottom } = useSafeAreaInsets()
24
+
25
+ const [_, props] = pipe(
26
+ useThemeComponentModifier('KeyboardAvoidingView'),
27
+ useFlexWrapperModifier,
28
+ useDisplayModifier,
29
+ useCursorModifier,
30
+ useAnimationModifier,
31
+ useStateModifier,
32
+ useSizeModifier,
33
+ usePositionModifier,
34
+ useOverflowModifier,
35
+ usePaddingModifier,
36
+ useMarginModifier,
37
+ useFlexModifier,
38
+ useBackgroundModifier,
39
+ useBorderModifier,
40
+ useShadowModifier
41
+ )([{}, rootProps])
42
+
43
+ return (
44
+ <AbsKeyboardAvoidingView
45
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
46
+ keyboardVerticalOffset={keyboardVerticalOffset + bottom}
47
+ {...props}
48
+ >
49
+ {children}
50
+ </AbsKeyboardAvoidingView>
51
+ )
52
+ }
@@ -0,0 +1,45 @@
1
+ import { Text } from '../text'
2
+ import { View } from './View'
3
+ import { useResponsiveConverter } from '../../modifiers/responsiveConverter'
4
+ import { useSafeAreaInsets } from '../../abstractions/helpers/useSafeAreaInsets'
5
+
6
+ export function TopBar({ right, left, WrapperView, children, ...rootProps }) {
7
+ const { top: safeTop } = useSafeAreaInsets()
8
+
9
+ const [_, props] = useResponsiveConverter([])([{}, rootProps])
10
+ let { useSafeArea = true, title, subtitle } = props
11
+
12
+ const hasContent = !!title || !!subtitle || !!children || !!right || !!left
13
+
14
+ WrapperView = WrapperView || View
15
+
16
+ return (
17
+ <WrapperView paddingT={useSafeArea && safeTop} {...props}>
18
+ {!!hasContent && (
19
+ <View minH="md" centerV row paddingH="md" paddingV="sm" gap="sm" fullW>
20
+ <View flex={1} toLeft>
21
+ {left}
22
+ </View>
23
+
24
+ <View center flex={3}>
25
+ {children || (
26
+ <Text center h6 numberOfLines={1}>
27
+ {title}
28
+ </Text>
29
+ )}
30
+
31
+ {subtitle && (
32
+ <Text center xs numberOfLines={1}>
33
+ {subtitle}
34
+ </Text>
35
+ )}
36
+ </View>
37
+
38
+ <View flex={1} toRight>
39
+ {right}
40
+ </View>
41
+ </View>
42
+ )}
43
+ </WrapperView>
44
+ )
45
+ }
@@ -1 +1,3 @@
1
1
  export { BottomDrawer } from './web/BottomDrawer'
2
+ export { ScrollView as DrawerScrollView } from '../../list/ScrollView'
3
+ export { FlatList as DrawerFlatList } from '../../list/FlatList'
@@ -1,4 +1,5 @@
1
1
  export { BottomDrawer } from './native/BottomDrawer'
2
- export { DrawerScrollView } from './native/DrawerScrollView'
2
+ export { DrawerScrollView, DrawerFlatList } from './native/DrawerScrollView'
3
+ export { createDrawerScrollComponent } from './native/createDrawerScrollComponent'
3
4
  export { DrawerHandle } from './native/DrawerHandle'
4
5
  export { DrawerProvider, useDrawerContext } from './native/DrawerContext'
@@ -1,4 +1,5 @@
1
1
  export { BottomDrawer } from './native/BottomDrawer'
2
- export { DrawerScrollView } from './native/DrawerScrollView'
2
+ export { DrawerScrollView, DrawerFlatList } from './native/DrawerScrollView'
3
+ export { createDrawerScrollComponent } from './native/createDrawerScrollComponent'
3
4
  export { DrawerHandle } from './native/DrawerHandle'
4
5
  export { DrawerProvider, useDrawerContext } from './native/DrawerContext'
@@ -6,7 +6,6 @@ import Animated, {
6
6
  useAnimatedStyle,
7
7
  withSpring,
8
8
  runOnJS,
9
- useAnimatedReaction,
10
9
  } from 'react-native-reanimated'
11
10
  import React from 'react'
12
11
 
@@ -47,9 +46,6 @@ function InnerContent({
47
46
  const colors = useColors()
48
47
 
49
48
  const translateY = useSharedValue(SCREEN_HEIGHT)
50
- const scrollOffset = useSharedValue(0)
51
- const scrollEnabled = useSharedValue(false)
52
- const isScrolling = useSharedValue(false)
53
49
  const snapIndex = useSharedValue(0)
54
50
  const velocityY = useSharedValue(0)
55
51
 
@@ -67,8 +63,6 @@ function InnerContent({
67
63
  snapIndex.value = 0
68
64
  } else {
69
65
  translateY.value = withSpring(SCREEN_HEIGHT, animationConfig, () => {
70
- scrollOffset.value = 0
71
- scrollEnabled.value = false
72
66
  runOnJS(setRender)(false)
73
67
  })
74
68
  snapIndex.value = -1
@@ -84,15 +78,6 @@ function InnerContent({
84
78
  return () => backHandler.remove()
85
79
  }, [open, onClose])
86
80
 
87
- useAnimatedReaction(
88
- () => translateY.value,
89
- (currentY) => {
90
- const atMaxSnapPoint = currentY <= SCREEN_HEIGHT - maxSnapPoint
91
- scrollEnabled.value = atMaxSnapPoint
92
- },
93
- []
94
- )
95
-
96
81
  let handleClose = React.useCallback(() => {
97
82
  onClose?.()
98
83
  }, [onClose])
@@ -112,9 +97,11 @@ function InnerContent({
112
97
 
113
98
  // contexto manual para gesto
114
99
  const gestureStartTranslateY = useSharedValue(0)
100
+ const panRef = React.useRef()
115
101
 
116
102
  const panGesture = React.useMemo(() => {
117
103
  return Gesture.Pan()
104
+ .withRef(panRef)
118
105
  .enabled(enableHandlePanningGesture || enableContentPanningGesture)
119
106
  .onStart(() => {
120
107
  gestureStartTranslateY.value = translateY.value
@@ -135,7 +122,11 @@ function InnerContent({
135
122
  const currentPosition = SCREEN_HEIGHT - translateY.value
136
123
  const shouldClose =
137
124
  !!handleClose &&
138
- ((velocityY.value > 2000 && currentPosition < minSnapPoint * 0.75) || currentPosition < minSnapPoint * 0.25)
125
+ (
126
+ velocityY.value > 1500 ||
127
+ (velocityY.value > 800 && currentPosition < minSnapPoint) ||
128
+ currentPosition < minSnapPoint * 0.35
129
+ )
139
130
 
140
131
  if (shouldClose) {
141
132
  runOnJS(handleClose)()
@@ -168,15 +159,18 @@ function InnerContent({
168
159
  const contextValue = React.useMemo(
169
160
  () => ({
170
161
  translateY,
171
- scrollOffset,
172
- scrollEnabled,
173
- isScrolling,
174
162
  snapIndex,
175
163
  maxSnapPoint,
176
164
  snapTo,
177
165
  animationConfig,
166
+ panRef,
167
+ normalizedSnapPoints,
168
+ SCREEN_HEIGHT,
169
+ minSnapPoint,
170
+ handleClose,
171
+ velocityY,
178
172
  }),
179
- [maxSnapPoint]
173
+ [maxSnapPoint, normalizedSnapPoints, SCREEN_HEIGHT, minSnapPoint, handleClose]
180
174
  )
181
175
 
182
176
  return (
@@ -1,83 +1,5 @@
1
- import React from 'react'
2
- import { ScrollView } from 'react-native'
3
- import Animated, { useAnimatedScrollHandler, useAnimatedReaction, runOnJS } from 'react-native-reanimated'
4
- import { useDrawerContext } from './DrawerContext'
1
+ import { FlatList, ScrollView } from '../../../list'
2
+ import { createDrawerScrollComponent } from './createDrawerScrollComponent'
5
3
 
6
- const AnimatedScrollView = Animated.createAnimatedComponent(ScrollView)
7
-
8
- export const DrawerScrollView = React.forwardRef((props, ref) => {
9
- const {
10
- children,
11
- onScroll,
12
- scrollEventThrottle = 16,
13
- showsVerticalScrollIndicator = true,
14
- bounces = true,
15
- ...scrollViewProps
16
- } = props
17
-
18
- const { scrollOffset, scrollEnabled, isScrolling } = useDrawerContext()
19
-
20
- const scrollRef = React.useRef(null)
21
-
22
- // Convert shared value to React state for the component
23
- const [isScrollEnabled, setIsScrollEnabled] = React.useState(true)
24
-
25
- React.useImperativeHandle(ref, () => scrollRef.current)
26
-
27
- // Handle scroll lock/unlock based on drawer position
28
- useAnimatedReaction(
29
- () => scrollEnabled.value,
30
- (enabled) => {
31
- if (!enabled && scrollOffset.value > 0) {
32
- runOnJS(() => {
33
- scrollRef.current?.scrollTo({ y: 0, animated: false })
34
- })()
35
- scrollOffset.value = 0
36
- }
37
- // Update React state
38
- runOnJS(setIsScrollEnabled)(enabled)
39
- },
40
- []
41
- )
42
-
43
- const handleScrollBeginDrag = React.useCallback(() => {
44
- isScrolling.value = true
45
- }, [isScrolling])
46
-
47
- const handleScrollEndDrag = React.useCallback(() => {
48
- isScrolling.value = false
49
- }, [isScrolling])
50
-
51
- const animatedScrollHandler = useAnimatedScrollHandler({
52
- onScroll: (event) => {
53
- scrollOffset.value = event.contentOffset.y
54
-
55
- if (onScroll) {
56
- runOnJS(onScroll)(event)
57
- }
58
- },
59
- onBeginDrag: () => {
60
- runOnJS(handleScrollBeginDrag)()
61
- },
62
- onEndDrag: () => {
63
- runOnJS(handleScrollEndDrag)()
64
- },
65
- })
66
-
67
- return (
68
- <AnimatedScrollView
69
- ref={scrollRef}
70
- style={{ flex: 1 }}
71
- scrollEnabled={isScrollEnabled}
72
- onScroll={animatedScrollHandler}
73
- scrollEventThrottle={scrollEventThrottle}
74
- showsVerticalScrollIndicator={showsVerticalScrollIndicator}
75
- bounces={bounces}
76
- {...scrollViewProps}
77
- >
78
- {children}
79
- </AnimatedScrollView>
80
- )
81
- })
82
-
83
- DrawerScrollView.displayName = 'DrawerScrollView'
4
+ export const DrawerScrollView = createDrawerScrollComponent(ScrollView)
5
+ export const DrawerFlatList = createDrawerScrollComponent(FlatList)