@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.
Files changed (220) hide show
  1. package/dist/DynamicStyleTag.js +5 -0
  2. package/dist/DynamicStyleTag.native.js +1 -0
  3. package/dist/NekoUI.js +1 -1
  4. package/dist/abstractions/ActivityIndicator.native.js +1 -1
  5. package/dist/abstractions/ActivityIndicator.web.js +1 -0
  6. package/dist/abstractions/AnimatedView.web.js +1 -0
  7. package/dist/abstractions/BlurView.web.js +1 -0
  8. package/dist/abstractions/FlatList.js +1 -0
  9. package/dist/abstractions/FlatList.native.js +1 -0
  10. package/dist/abstractions/FlatList.web.js +1 -0
  11. package/dist/abstractions/ScrollView.web.js +1 -0
  12. package/dist/abstractions/StaticList.js +1 -0
  13. package/dist/abstractions/helpers/storage.js +1 -0
  14. package/dist/abstractions/helpers/storage.native.js +1 -0
  15. package/dist/abstractions/helpers/useSafeAreaInsets.js +1 -0
  16. package/dist/abstractions/helpers/useSafeAreaInsets.native.js +1 -0
  17. package/dist/components/actions/Button.js +1 -1
  18. package/dist/components/actions/Dropdown.js +1 -1
  19. package/dist/components/actions/FloatingButton.js +1 -0
  20. package/dist/components/actions/index.js +1 -1
  21. package/dist/components/actions/menu/VerticalMenu.js +1 -1
  22. package/dist/components/calendar/_helpers/calendarDays.js +1 -1
  23. package/dist/components/feedback/alerter.js +1 -1
  24. package/dist/components/feedback/confirmer.js +1 -1
  25. package/dist/components/helpers/ConditionalLazyRender.js +1 -0
  26. package/dist/components/helpers/LazyAction.js +1 -0
  27. package/dist/components/helpers/LazyRender.js +1 -1
  28. package/dist/components/helpers/LazyRender.native.js +1 -1
  29. package/dist/components/helpers/index.js +1 -1
  30. package/dist/components/index.js +1 -1
  31. package/dist/components/inputs/DateInput.js +1 -1
  32. package/dist/components/inputs/InputWrapper.js +1 -1
  33. package/dist/components/inputs/LinkInput.js +1 -1
  34. package/dist/components/inputs/NumberInput.js +1 -0
  35. package/dist/components/inputs/Picker.js +1 -1
  36. package/dist/components/inputs/Radio.js +1 -1
  37. package/dist/components/inputs/RateInput.js +1 -0
  38. package/dist/components/inputs/SegmentedPicker.js +1 -0
  39. package/dist/components/inputs/Select.js +1 -0
  40. package/dist/components/inputs/datePicker/DayPicker.js +1 -1
  41. package/dist/components/inputs/datePicker/MonthPicker.js +1 -1
  42. package/dist/components/inputs/datePicker/QuarterPicker.js +1 -1
  43. package/dist/components/inputs/datePicker/WeekPicker.js +1 -1
  44. package/dist/components/inputs/datePicker/YearPicker.js +1 -1
  45. package/dist/components/inputs/index.js +1 -1
  46. package/dist/components/layout/Layout.js +1 -1
  47. package/dist/components/list/FlatList.js +1 -0
  48. package/dist/components/list/index.js +1 -1
  49. package/dist/components/presentation/Rate.js +1 -0
  50. package/dist/components/presentation/RateTag.js +1 -0
  51. package/dist/components/presentation/Result.js +1 -1
  52. package/dist/components/presentation/Tooltip.js +1 -1
  53. package/dist/components/presentation/index.js +1 -1
  54. package/dist/components/state/LoadingView.js +1 -1
  55. package/dist/components/structure/Accordion.js +1 -1
  56. package/dist/components/structure/Row.js +1 -1
  57. package/dist/components/structure/Segment.js +1 -0
  58. package/dist/components/structure/View.js +1 -1
  59. package/dist/components/structure/bottomDrawer/native/BottomDrawer.js +1 -1
  60. package/dist/components/structure/bottomDrawer/native/utils.js +1 -1
  61. package/dist/components/structure/bottomDrawer/web/BottomDrawer.js +1 -1
  62. package/dist/components/structure/index.js +1 -1
  63. package/dist/components/structure/overlay/OverlayHandler.js +1 -1
  64. package/dist/components/structure/popover/Popover.js +1 -1
  65. package/dist/components/structure/popover/Popover.native.js +1 -1
  66. package/dist/components/structure/popover/Popover_BU.js +1 -0
  67. package/dist/components/tabs/ActiveTabContent.js +1 -0
  68. package/dist/components/tabs/TabsHandler.js +1 -0
  69. package/dist/components/tabs/TabsMenu.js +1 -0
  70. package/dist/components/tabs/index.js +1 -0
  71. package/dist/components/theme/ThemePicker.js +1 -0
  72. package/dist/components/theme/ThemePickerDrawer.js +1 -0
  73. package/dist/components/theme/ThemeStatusBar.js +1 -0
  74. package/dist/components/theme/ThemeStatusBar.native.js +1 -0
  75. package/dist/components/theme/ThemeThumb.js +1 -0
  76. package/dist/components/theme/index.js +1 -0
  77. package/dist/helpers/index.js +1 -1
  78. package/dist/helpers/storage.js +1 -0
  79. package/dist/helpers/string.js +1 -1
  80. package/dist/i18n/I18n.js +1 -0
  81. package/dist/i18n/I18nProvider.js +1 -0
  82. package/dist/i18n/index.js +1 -0
  83. package/dist/index.css +4 -0
  84. package/dist/index.js +1 -1
  85. package/dist/modifiers/animations/fadeEffect.web.js +1 -0
  86. package/dist/modifiers/animations/scrollEffect.web.js +1 -0
  87. package/dist/modifiers/animations/slideEffect.web.js +1 -0
  88. package/dist/modifiers/fullColor.js +1 -1
  89. package/dist/modifiers/overflow.js +1 -1
  90. package/dist/modifiers/position.js +1 -1
  91. package/dist/theme/ThemeHandler.js +1 -1
  92. package/dist/theme/default/base.js +1 -1
  93. package/dist/theme/default/blackTheme.js +1 -1
  94. package/dist/theme/default/cyberpunkTheme.js +1 -1
  95. package/dist/theme/default/darkTheme.js +1 -1
  96. package/dist/theme/default/deepWoodsTheme.js +1 -1
  97. package/dist/theme/default/forestTheme.js +1 -1
  98. package/dist/theme/default/hackerTheme.js +1 -1
  99. package/dist/theme/default/lightTheme.js +1 -1
  100. package/dist/theme/default/midnightTheme.js +1 -1
  101. package/dist/theme/default/msdosTheme.js +1 -1
  102. package/dist/theme/default/oceanTheme.js +1 -1
  103. package/dist/theme/default/paperTheme.js +1 -0
  104. package/dist/theme/default/pastelTheme.js +1 -1
  105. package/dist/theme/default/sunsetTheme.js +1 -1
  106. package/dist/theme/default/themes.js +1 -1
  107. package/dist/theme/format/formatTheme.js +1 -1
  108. package/dist/theme/helpers/contrastColor.js +1 -1
  109. package/package.json +1 -1
  110. package/src/DynamicStyleTag.js +21 -0
  111. package/src/DynamicStyleTag.native.js +3 -0
  112. package/src/NekoUI.js +21 -4
  113. package/src/abstractions/ActivityIndicator.native.js +3 -4
  114. package/src/abstractions/ActivityIndicator.web.js +43 -0
  115. package/src/abstractions/AnimatedView.web.js +3 -0
  116. package/src/abstractions/BlurView.web.js +39 -0
  117. package/src/abstractions/FlatList.js +3 -0
  118. package/src/abstractions/FlatList.native.js +36 -0
  119. package/src/abstractions/FlatList.web.js +3 -0
  120. package/src/abstractions/ScrollView.web.js +3 -0
  121. package/src/abstractions/StaticList.js +51 -0
  122. package/src/abstractions/Text.web.js +15 -0
  123. package/src/abstractions/helpers/storage.js +32 -0
  124. package/src/abstractions/helpers/storage.native.js +34 -0
  125. package/src/abstractions/helpers/useSafeAreaInsets.js +3 -0
  126. package/src/abstractions/helpers/useSafeAreaInsets.native.js +3 -0
  127. package/src/components/actions/Button.js +1 -0
  128. package/src/components/actions/Dropdown.js +24 -5
  129. package/src/components/actions/FloatingButton.js +87 -0
  130. package/src/components/actions/index.js +1 -0
  131. package/src/components/actions/menu/VerticalMenu.js +30 -5
  132. package/src/components/calendar/_helpers/calendarDays.js +2 -0
  133. package/src/components/feedback/alerter.js +1 -1
  134. package/src/components/feedback/confirmer.js +2 -2
  135. package/src/components/helpers/ConditionalLazyRender.js +6 -0
  136. package/src/components/helpers/LazyAction.js +22 -0
  137. package/src/components/helpers/LazyRender.js +2 -2
  138. package/src/components/helpers/LazyRender.native.js +1 -1
  139. package/src/components/helpers/index.js +1 -0
  140. package/src/components/index.js +2 -0
  141. package/src/components/inputs/DateInput.js +11 -1
  142. package/src/components/inputs/InputWrapper.js +0 -1
  143. package/src/components/inputs/LinkInput.js +3 -3
  144. package/src/components/inputs/NumberInput.js +105 -0
  145. package/src/components/inputs/Picker.js +61 -9
  146. package/src/components/inputs/Radio.js +1 -1
  147. package/src/components/inputs/RateInput.js +62 -0
  148. package/src/components/inputs/SegmentedPicker.js +62 -0
  149. package/src/components/inputs/Select.js +189 -0
  150. package/src/components/inputs/datePicker/DayPicker.js +4 -5
  151. package/src/components/inputs/datePicker/MonthPicker.js +2 -2
  152. package/src/components/inputs/datePicker/QuarterPicker.js +2 -2
  153. package/src/components/inputs/datePicker/WeekPicker.js +2 -2
  154. package/src/components/inputs/datePicker/YearPicker.js +9 -6
  155. package/src/components/inputs/index.js +4 -0
  156. package/src/components/layout/Layout.js +1 -1
  157. package/src/components/list/FlatList.js +91 -0
  158. package/src/components/list/index.js +1 -0
  159. package/src/components/presentation/Rate.js +58 -0
  160. package/src/components/presentation/RateTag.js +35 -0
  161. package/src/components/presentation/Result.js +2 -2
  162. package/src/components/presentation/Tooltip.js +1 -0
  163. package/src/components/presentation/index.js +2 -0
  164. package/src/components/state/LoadingView.js +10 -1
  165. package/src/components/structure/Accordion.js +1 -1
  166. package/src/components/structure/Row.js +9 -1
  167. package/src/components/structure/Segment.js +51 -0
  168. package/src/components/structure/View.js +2 -0
  169. package/src/components/structure/bottomDrawer/native/BottomDrawer.js +19 -3
  170. package/src/components/structure/bottomDrawer/native/utils.js +29 -22
  171. package/src/components/structure/bottomDrawer/web/BottomDrawer.js +3 -1
  172. package/src/components/structure/index.js +1 -0
  173. package/src/components/structure/overlay/OverlayHandler.js +6 -1
  174. package/src/components/structure/popover/Popover.js +44 -21
  175. package/src/components/structure/popover/Popover.native.js +3 -2
  176. package/src/components/structure/popover/Popover_BU.js +157 -0
  177. package/src/components/tabs/ActiveTabContent.js +35 -0
  178. package/src/components/tabs/TabsHandler.js +16 -0
  179. package/src/components/tabs/TabsMenu.js +15 -0
  180. package/src/components/tabs/index.js +3 -0
  181. package/src/components/theme/ThemePicker.js +49 -0
  182. package/src/components/theme/ThemePickerDrawer.js +13 -0
  183. package/src/components/theme/ThemeStatusBar.js +3 -0
  184. package/src/components/theme/ThemeStatusBar.native.js +9 -0
  185. package/src/components/theme/ThemeThumb.js +98 -0
  186. package/src/components/theme/index.js +3 -0
  187. package/src/helpers/index.js +1 -0
  188. package/src/helpers/storage.js +54 -0
  189. package/src/helpers/string.js +18 -1
  190. package/src/i18n/I18n.js +97 -0
  191. package/src/i18n/I18nProvider.js +40 -0
  192. package/src/i18n/index.js +2 -0
  193. package/src/index.css +4 -0
  194. package/src/index.js +1 -0
  195. package/src/modifiers/animations/fadeEffect.web.js +3 -0
  196. package/src/modifiers/animations/scrollEffect.web.js +3 -0
  197. package/src/modifiers/animations/slideEffect.web.js +3 -0
  198. package/src/modifiers/fullColor.js +2 -2
  199. package/src/modifiers/overflow.js +6 -1
  200. package/src/modifiers/position.js +7 -0
  201. package/src/theme/ThemeHandler.js +18 -2
  202. package/src/theme/default/base.js +12 -8
  203. package/src/theme/default/blackTheme.js +4 -1
  204. package/src/theme/default/cyberpunkTheme.js +3 -1
  205. package/src/theme/default/darkTheme.js +3 -1
  206. package/src/theme/default/deepWoodsTheme.js +4 -2
  207. package/src/theme/default/forestTheme.js +3 -1
  208. package/src/theme/default/hackerTheme.js +3 -1
  209. package/src/theme/default/lightTheme.js +3 -1
  210. package/src/theme/default/midnightTheme.js +3 -1
  211. package/src/theme/default/msdosTheme.js +18 -4
  212. package/src/theme/default/oceanTheme.js +4 -2
  213. package/src/theme/default/paperTheme.js +35 -0
  214. package/src/theme/default/pastelTheme.js +3 -1
  215. package/src/theme/default/sunsetTheme.js +5 -3
  216. package/src/theme/default/themes.js +7 -10
  217. package/src/theme/format/formatTheme.js +9 -3
  218. package/src/theme/helpers/contrastColor.js +49 -11
  219. package/dist/abstractions/TouchableOpacity.web.js +0 -1
  220. package/src/abstractions/TouchableOpacity.web.js +0 -3
@@ -0,0 +1,3 @@
1
+ export function DynamicStyleTag() {
2
+ return false
3
+ }
package/src/NekoUI.js CHANGED
@@ -1,22 +1,39 @@
1
+ import { DynamicStyleTag } from './DynamicStyleTag'
2
+ import { I18nProvider } from './i18n'
1
3
  import { ModalsHandler } from './components/structure/modal/handler/ModalsHandler'
2
4
  import { NotificationsHandler } from './components/feedback/notifications/NotificationsHandler'
3
5
  import { OverlayHandler } from './components/structure/overlay/OverlayHandler'
4
6
  import { PortalHandler } from './components/helpers/PortalHandler'
5
7
  import { ResponsiveHandler } from './responsive/ResponsiveHandler'
6
8
  import { ThemeHandler } from './theme/ThemeHandler'
9
+ import { ThemePickerDrawer } from './components/theme'
10
+ import { useThemeHandler } from './theme'
7
11
 
8
- export function NekoUI({ children, ...props }) {
12
+ export function NekoUI({ children, i18n, ...props }) {
9
13
  return (
10
14
  <ThemeHandler {...props}>
15
+ <DynamicStyleTag />
11
16
  <ResponsiveHandler>
12
17
  <PortalHandler>
13
18
  <ModalsHandler>
14
- <NotificationsHandler>
15
- <OverlayHandler>{children}</OverlayHandler>
16
- </NotificationsHandler>
19
+ <I18nProvider i18n={i18n}>
20
+ <NotificationsHandler>
21
+ <OverlayHandler>
22
+ {children}
23
+ <FixedComponents />
24
+ </OverlayHandler>
25
+ </NotificationsHandler>
26
+ </I18nProvider>
17
27
  </ModalsHandler>
18
28
  </PortalHandler>
19
29
  </ResponsiveHandler>
20
30
  </ThemeHandler>
21
31
  )
22
32
  }
33
+
34
+ // TODO: Move to ModalRouter when its ready
35
+ function FixedComponents() {
36
+ const { themePickerOpen, setThemePickerOpen } = useThemeHandler()
37
+
38
+ return <ThemePickerDrawer open={themePickerOpen} onClose={() => setThemePickerOpen(false)} />
39
+ }
@@ -1,6 +1,6 @@
1
- import tinycolor from 'tinycolor2'
2
- import { Animated, Easing } from 'react-native'
1
+ import { Animated, Easing, Platform } from 'react-native'
3
2
  import React from 'react'
3
+ import tinycolor from 'tinycolor2'
4
4
 
5
5
  export function AbsActivityIndicator({ size = 20, color, style }) {
6
6
  const spinValue = React.useRef(new Animated.Value(0)).current
@@ -12,7 +12,7 @@ export function AbsActivityIndicator({ size = 20, color, style }) {
12
12
  toValue: 1,
13
13
  duration: 1000,
14
14
  easing: Easing.linear,
15
- useNativeDriver: true,
15
+ useNativeDriver: Platform.OS !== 'web',
16
16
  })
17
17
  )
18
18
  spinAnimation.start()
@@ -26,7 +26,6 @@ export function AbsActivityIndicator({ size = 20, color, style }) {
26
26
 
27
27
  const borderWidth = size / 8
28
28
 
29
- console.log(color, bg)
30
29
  return (
31
30
  <Animated.View
32
31
  style={{
@@ -0,0 +1,43 @@
1
+ import tinycolor from 'tinycolor2'
2
+ import { Animated, Easing } from 'react-native'
3
+ import React from 'react'
4
+
5
+ export function AbsActivityIndicator({ size = 20, color, style }) {
6
+ const spinValue = React.useRef(new Animated.Value(0)).current
7
+ const bg = tinycolor(color).setAlpha(0.2).toString()
8
+
9
+ React.useEffect(() => {
10
+ const spinAnimation = Animated.loop(
11
+ Animated.timing(spinValue, {
12
+ toValue: 1,
13
+ duration: 1000,
14
+ easing: Easing.linear,
15
+ useNativeDriver: false,
16
+ })
17
+ )
18
+ spinAnimation.start()
19
+ return () => spinAnimation.stop()
20
+ }, [spinValue])
21
+
22
+ const spin = spinValue.interpolate({
23
+ inputRange: [0, 1],
24
+ outputRange: ['0deg', '360deg'],
25
+ })
26
+
27
+ const borderWidth = size / 8
28
+
29
+ return (
30
+ <Animated.View
31
+ style={{
32
+ width: size,
33
+ height: size,
34
+ borderRadius: size / 2,
35
+ borderWidth: borderWidth,
36
+ borderColor: `${bg}`,
37
+ borderTopColor: color,
38
+ transform: [{ rotate: spin }],
39
+ ...style,
40
+ }}
41
+ />
42
+ )
43
+ }
@@ -0,0 +1,3 @@
1
+ import { AbsAnimatedView as NativeAbsAnimatedView } from './AnimatedView.native'
2
+
3
+ export const AbsAnimatedView = NativeAbsAnimatedView
@@ -0,0 +1,39 @@
1
+ import { AbsView } from './View'
2
+
3
+ let AbsBlurView
4
+
5
+ try {
6
+ const { BlurView } = require('expo-blur') || {}
7
+ AbsBlurView = ({ intensity, tint, disabledForAndroid, style, children, ...props }) => {
8
+ return (
9
+ <BlurView
10
+ intensity={intensity}
11
+ tint={tint}
12
+ style={[style, { overflow: 'hidden' }]}
13
+ experimentalBlurMethod={disabledForAndroid ? 'none' : 'dimezisBlurView'}
14
+ >
15
+ {children}
16
+ </BlurView>
17
+ )
18
+
19
+ // return (
20
+ // <AbsView style={[style, { overflow: 'hidden' }]} {...props}>
21
+ // <BlurView
22
+ // intensity={intensity}
23
+ // tint={tint}
24
+ // style={[style, { width: '100%' }]}
25
+ // experimentalBlurMethod={disabledForAndroid ? 'none' : 'dimezisBlurView'}
26
+ // >
27
+ // {children}
28
+ // </BlurView>
29
+ // </AbsView>
30
+ // )
31
+ }
32
+ } catch {
33
+ AbsBlurView = (props) => {
34
+ console.warn('expo-blur not instaled.')
35
+ return <AbsView {...props} />
36
+ }
37
+ }
38
+
39
+ export { AbsBlurView }
@@ -0,0 +1,3 @@
1
+ import { AbsStaticList } from './StaticList'
2
+
3
+ export const AbsFlatList = AbsStaticList
@@ -0,0 +1,36 @@
1
+ import { FlatList } from 'react-native'
2
+
3
+ export const AbsFlatList = ({
4
+ style: { height, width, ...style },
5
+ ItemSeparatorComponent,
6
+ Separator,
7
+ renderSeparator,
8
+ ListEmptyComponent,
9
+ Empty,
10
+ renderEmpty,
11
+ ListFooterComponent,
12
+ Footer,
13
+ renderFooter,
14
+ ListHeaderComponent,
15
+ Header,
16
+ renderHeader,
17
+ ...props
18
+ }) => {
19
+ ItemSeparatorComponent = ItemSeparatorComponent || Separator || renderSeparator
20
+ ListEmptyComponent = ListEmptyComponent || Empty || renderEmpty
21
+ ListFooterComponent = ListFooterComponent || Footer || renderFooter
22
+ ListHeaderComponent = ListHeaderComponent || Header || renderHeader
23
+
24
+ return (
25
+ <FlatList
26
+ height={height}
27
+ width={width}
28
+ {...props}
29
+ ItemSeparatorComponent={ItemSeparatorComponent}
30
+ ListEmptyComponent={ListEmptyComponent}
31
+ ListFooterComponent={ListFooterComponent}
32
+ ListHeaderComponent={ListHeaderComponent}
33
+ contentContainerStyle={style}
34
+ />
35
+ )
36
+ }
@@ -0,0 +1,3 @@
1
+ import { AbsFlatList as NativeFlatList } from './FlatList.native'
2
+
3
+ export const AbsFlatList = NativeFlatList
@@ -0,0 +1,3 @@
1
+ import { AbsScrollView as NativeAbsScrollView } from './ScrollView.native'
2
+
3
+ export const AbsScrollView = NativeAbsScrollView
@@ -0,0 +1,51 @@
1
+ import React from 'react'
2
+
3
+ import { AbsView } from './View'
4
+ import { LazyAction } from '../components/helpers/LazyAction'
5
+
6
+ const defaultRender = () => false
7
+
8
+ export function AbsStaticList({
9
+ data,
10
+ renderItem,
11
+ ItemSeparatorComponent,
12
+ Separator,
13
+ renderSeparator,
14
+ ListEmptyComponent,
15
+ Empty,
16
+ renderEmpty,
17
+ ListFooterComponent,
18
+ Footer,
19
+ renderFooter,
20
+ ListHeaderComponent,
21
+ Header,
22
+ renderHeader,
23
+ keyExtractor,
24
+ onEndReached,
25
+ ...props
26
+ }) {
27
+ ItemSeparatorComponent = ItemSeparatorComponent || Separator || renderSeparator || defaultRender
28
+ ListEmptyComponent = ListEmptyComponent || Empty || renderEmpty || defaultRender
29
+ ListFooterComponent = ListFooterComponent || Footer || renderFooter || defaultRender
30
+ ListHeaderComponent = ListHeaderComponent || Header || renderHeader || defaultRender
31
+ keyExtractor = keyExtractor || ((item, index) => index)
32
+ renderItem = renderItem || defaultRender
33
+
34
+ return (
35
+ <AbsView {...props}>
36
+ <ListHeaderComponent />
37
+
38
+ {!data?.length && <ListEmptyComponent />}
39
+ {data?.map?.((item, index) => (
40
+ <React.Fragment key={keyExtractor(item, index)}>
41
+ {index !== 0 && <ItemSeparatorComponent />}
42
+ {renderItem({ item, index })}
43
+ </React.Fragment>
44
+ ))}
45
+
46
+ <LazyAction action={onEndReached} destroyOffScreen />
47
+
48
+ <ListFooterComponent />
49
+ </AbsView>
50
+ )
51
+ }
@@ -1,3 +1,18 @@
1
+ // export const AbsText = ({ numberOfLines, style, ...props }) => {
2
+ // style = style || {}
3
+
4
+ // const limitLinesStyle = !!numberOfLines
5
+ // ? {
6
+ // display: '-webkit-box',
7
+ // WebkitLineClamp: numberOfLines,
8
+ // WebkitBoxOrient: 'vertical',
9
+ // overflow: 'hidden',
10
+ // }
11
+ // : {}
12
+
13
+ // return <AbsText {...props} style={[limitLinesStyle, style]} />
14
+ // }
15
+
1
16
  import { Text as RNText } from 'react-native'
2
17
 
3
18
  export const AbsText = RNText
@@ -0,0 +1,32 @@
1
+ function set(key, value) {
2
+ return localStorage.setItem(key, value)
3
+ }
4
+
5
+ function setAsync(key, value) {
6
+ return Promise.resulve(set(key, value))
7
+ }
8
+
9
+ function get(key) {
10
+ return localStorage.getItem(key)
11
+ }
12
+
13
+ function getAsync(key) {
14
+ return Promise.resulve(get(key))
15
+ }
16
+
17
+ function remove(key) {
18
+ return localStorage.removeItem(key)
19
+ }
20
+
21
+ function removeAsync(key) {
22
+ return Promise.resulve(remove(key))
23
+ }
24
+
25
+ export const AbsStorage = {
26
+ set,
27
+ setAsync,
28
+ get,
29
+ getAsync,
30
+ remove,
31
+ removeAsync,
32
+ }
@@ -0,0 +1,34 @@
1
+ let set = () => console.warn('expo-sqlite not installed. Neko Storage needs expo-sqlite to work properly')
2
+ let setAsync = () => Promise.resolve(set())
3
+
4
+ let get = () => console.warn('expo-sqlite not installed. Neko Storage needs expo-sqlite to work properly')
5
+ let getAsync = () => Promise.resolve(get())
6
+
7
+ let remove = () => console.warn('expo-sqlite not installed. Neko Storage needs expo-sqlite to work properly')
8
+ let removeAsync = () => Promise.resolve(remove())
9
+
10
+ try {
11
+ const StorageModule = require('expo-sqlite/kv-store')
12
+ if (StorageModule?.default) {
13
+ const Storage = StorageModule.default
14
+ set = Storage.setItemSync.bind(Storage)
15
+ setAsync = Storage.setItem.bind(Storage)
16
+
17
+ get = Storage.getItemSync.bind(Storage)
18
+ getAsync = Storage.getItem.bind(Storage)
19
+
20
+ remove = Storage.removeItemSync.bind(Storage)
21
+ removeAsync = Storage.removeItem.bind(Storage)
22
+ }
23
+ } catch (e) {
24
+ console.log('expo-sqlite not available:', e)
25
+ }
26
+
27
+ export const AbsStorage = {
28
+ set,
29
+ setAsync,
30
+ get,
31
+ getAsync,
32
+ remove,
33
+ removeAsync,
34
+ }
@@ -0,0 +1,3 @@
1
+ export const useSafeAreaInsets = () => {
2
+ return { top: 0, bottom: 0, left: 0, right: 0 }
3
+ }
@@ -0,0 +1,3 @@
1
+ import { useSafeAreaInsets as _useSafeAreaInsets } from 'react-native-safe-area-context'
2
+
3
+ export const useSafeAreaInsets = _useSafeAreaInsets
@@ -27,6 +27,7 @@ const DEFAULT_PROPS = ([{ sizeCode }]) => ({
27
27
  br: sizeCode,
28
28
  border: 1,
29
29
  center: true,
30
+ pointer: true,
30
31
  hover: {
31
32
  opacity: 0.7,
32
33
  },
@@ -5,8 +5,10 @@ import { Link } from './Link'
5
5
  import { Menu } from './menu/Menu'
6
6
  import { Popover } from '../structure/popover/Popover'
7
7
  import { View } from '../structure/View'
8
+ import { useResponsiveValue } from '../../responsive'
8
9
  import { useThemeComponentModifier } from '../../modifiers/themeComponent'
9
10
 
11
+ // TODO: Refactor to use default values
10
12
  export function Dropdown({ items, ...rootProps }) {
11
13
  const [_, formattedProps] = pipe(
12
14
  useThemeComponentModifier('Dropdown')
@@ -21,7 +23,7 @@ export function Dropdown({ items, ...rootProps }) {
21
23
  // useFlexModifier
22
24
  )([{}, rootProps])
23
25
 
24
- const {
26
+ let {
25
27
  onChange,
26
28
  label,
27
29
  trigger = 'click',
@@ -31,24 +33,40 @@ export function Dropdown({ items, ...rootProps }) {
31
33
  popoverProps,
32
34
  iconLabelProps,
33
35
  children,
36
+ placement,
37
+ gap,
38
+ useBottomDrawer,
34
39
  ...props
35
40
  } = formattedProps
36
41
 
42
+ useBottomDrawer = useResponsiveValue(useBottomDrawer || { native: true, sm: true, md: true })
43
+
37
44
  return (
38
45
  <View className="neko-dropdown" {...props}>
39
46
  <Popover
40
47
  useParentMinWidth
41
- placement="bottomLeft"
48
+ placement={placement || 'bottomLeft'}
42
49
  trigger={trigger}
43
- padding="xs"
44
- useBottomDrawer={{ native: true, sm: true, md: true }}
50
+ padding={0}
51
+ // In case its web use the Drawer component
52
+ contentProps={{ padding: 0 }}
53
+ useBottomDrawer={useBottomDrawer}
45
54
  {...popoverProps}
46
55
  renderContent={({ onClose }) => {
47
56
  const handleChange = (...params) => {
48
57
  if (onChange) onChange(...params)
49
58
  onClose()
50
59
  }
51
- return <Menu vertical items={items} onChange={handleChange} linkPaddingH="xs" />
60
+ return (
61
+ <Menu
62
+ vertical
63
+ items={items}
64
+ onChange={handleChange}
65
+ linkPaddingH={useBottomDrawer ? 'md' : 'sm'}
66
+ linkMinHeight={useBottomDrawer ? 'xl' : 'md'}
67
+ withDivider={useBottomDrawer}
68
+ />
69
+ )
52
70
  }}
53
71
  >
54
72
  {children || (
@@ -59,6 +77,7 @@ export function Dropdown({ items, ...rootProps }) {
59
77
  strong={strong}
60
78
  color={color}
61
79
  invert
80
+ gap={gap}
62
81
  {...iconLabelProps}
63
82
  />
64
83
  </Link>
@@ -0,0 +1,87 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { AbsTouchableOpacity } from '../../abstractions/TouchableOpacity'
4
+ import { Icon } from '../presentation'
5
+ import { Loading } from '../state'
6
+ import { moveScale } from '../../theme/helpers/sizeScale'
7
+ import { useBackgroundModifier } from '../../modifiers/background'
8
+ import { useBorderModifier } from '../../modifiers/border'
9
+ import { useColorConverter } from '../../modifiers/colorConverter'
10
+ import { useCursorModifier } from '../../modifiers/cursor'
11
+ import { useDefaultModifier } from '../../modifiers/default'
12
+ import { useDisplayModifier } from '../../modifiers/display'
13
+ import { useFlexModifier } from '../../modifiers/flex'
14
+ import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
15
+ import { useFullColorModifier } from '../../modifiers/fullColor'
16
+ import { useHoverConverter } from '../../modifiers/hover'
17
+ import { useMarginModifier } from '../../modifiers/margin'
18
+ import { usePaddingModifier } from '../../modifiers/padding'
19
+ import { usePositionModifier } from '../../modifiers/position'
20
+ import { useSafeAreaInsets } from '../../abstractions/helpers/useSafeAreaInsets'
21
+ import { useSizeConverter } from '../../modifiers/sizeConverter'
22
+ import { useSizeModifier } from '../../modifiers/size'
23
+ import { useStateModifier } from '../../modifiers/state'
24
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
25
+
26
+ const DEFAULT_PROPS =
27
+ ({ bottomInset }) =>
28
+ ([{ sizeCode }, { square }]) => {
29
+ sizeCode = moveScale(sizeCode, 1)
30
+
31
+ return {
32
+ absolute: true,
33
+ shadow: true,
34
+ bottom: 'md',
35
+ marginB: bottomInset,
36
+ right: 'md',
37
+ round: !square,
38
+ ration: 1,
39
+ padding: 'xxxs',
40
+ height: sizeCode,
41
+ width: sizeCode,
42
+ br: sizeCode,
43
+ border: 1,
44
+ center: true,
45
+ pointer: true,
46
+ hover: {
47
+ opacity: 0.7,
48
+ },
49
+ }
50
+ }
51
+
52
+ export function FloatingButton({ useSafeArea = true, ...rootProps }) {
53
+ const insets = useSafeAreaInsets()
54
+ const bottomInset = useSafeArea ? insets.bottom : 0
55
+
56
+ let [{ loading, fontColor, color, sizeCode }, formattedProps] = pipe(
57
+ useColorConverter('primary'),
58
+ useSizeConverter('elementHeights', 'md'),
59
+ useThemeComponentModifier('FloatingButton'),
60
+ useDefaultModifier(DEFAULT_PROPS({ bottomInset })),
61
+ useHoverConverter,
62
+ useCursorModifier,
63
+ useFullColorModifier,
64
+ useDisplayModifier,
65
+ useStateModifier,
66
+ useSizeModifier,
67
+ usePositionModifier,
68
+ usePaddingModifier,
69
+ useMarginModifier,
70
+ useFlexModifier,
71
+ useFlexWrapperModifier,
72
+ useBackgroundModifier,
73
+ useBorderModifier
74
+ )([{}, rootProps])
75
+ sizeCode = moveScale(sizeCode, 1)
76
+
77
+ const { icon, iconProps, size, ...props } = formattedProps
78
+
79
+ let content = <Icon flex color={fontColor} size={sizeCode} name={icon} loading={loading} {...iconProps} />
80
+ if (loading) content = <Loading size={sizeCode} color={fontColor} />
81
+
82
+ return (
83
+ <AbsTouchableOpacity className="neko-floating-button neko-wave-click-effect" type="button" {...props}>
84
+ {content}
85
+ </AbsTouchableOpacity>
86
+ )
87
+ }
@@ -1,4 +1,5 @@
1
1
  export * from './Button'
2
+ export * from './FloatingButton'
2
3
  export * from './Link'
3
4
  export * from './Pressable'
4
5
  export * from './Dropdown'
@@ -5,9 +5,11 @@ import tinycolor from 'tinycolor2'
5
5
  import { Divider } from '../../helpers/Separator'
6
6
  import { IconText } from '../../presentation/IconLabel'
7
7
  import { Link } from '../Link'
8
+ import { List } from '../../list/FlatList'
8
9
  import { SubmenuWrapper } from './SubmenuWrapper'
9
10
  import { Text } from '../../text/Text'
10
11
  import { View } from '../../structure/View'
12
+ import { moveScale } from '../../../theme/helpers/sizeScale'
11
13
  import { useColorConverter } from '../../../modifiers/colorConverter'
12
14
  import { useSizeConverter } from '../../../modifiers/sizeConverter'
13
15
  import { useThemeComponentModifier } from '../../../modifiers/themeComponent'
@@ -15,7 +17,8 @@ import { useThemeComponentModifier } from '../../../modifiers/themeComponent'
15
17
  function LinkItem({
16
18
  item,
17
19
  linkPaddingH = 'md',
18
- linkPaddingV = 'sm',
20
+ linkPaddingV = 'xs',
21
+ linkMinHeight,
19
22
  handlePress,
20
23
  linkProps,
21
24
  activeIndex,
@@ -31,6 +34,7 @@ function LinkItem({
31
34
  if (!active && activeIndex >= 0) active = activeIndex === index
32
35
  if (!active && activeKey !== undefined) active = activeKey === item.key
33
36
  const bg = active && tinycolor(color).setAlpha(0.03).toString()
37
+ linkMinHeight = linkMinHeight || moveScale(sizeCode, 1)
34
38
 
35
39
  return (
36
40
  <SubmenuWrapper item={item} onChange={handlePress} activeKey={activeKey} color={color}>
@@ -39,10 +43,10 @@ function LinkItem({
39
43
  center
40
44
  paddingH={linkPaddingH}
41
45
  paddingV={linkPaddingV}
46
+ minHeight={linkMinHeight}
42
47
  marginR={3}
43
48
  borderL={3}
44
- marginV={-4}
45
- borderColor={active ? activeColor : 'transparent'}
49
+ brColor={active ? activeColor : 'transparent'}
46
50
  bg={bg}
47
51
  transition="border-color 0.5s ease, background 0.3s ease"
48
52
  hover={{ br: 0 }}
@@ -61,7 +65,7 @@ function DividerItem({ linkPaddingH = 'md', item }) {
61
65
  return (
62
66
  <>
63
67
  {content}
64
- <Text size="xs" color="text4" paddingH={linkPaddingH || 'md'} strong {...item} />
68
+ <Text size="xs" color="text4" paddingV="xs" paddingH={linkPaddingH || 'md'} strong {...item} />
65
69
  </>
66
70
  )
67
71
  }
@@ -78,7 +82,7 @@ export function VerticalMenu(rootProps) {
78
82
  useThemeComponentModifier('VerticalMenu') //
79
83
  )([{}, rootProps])
80
84
 
81
- let { gap = 'sm', items, onChange, onChangeIndex, ...props } = formattedProps
85
+ let { gap = 'sm', items, onChange, onChangeIndex, withDivider, ...props } = formattedProps
82
86
 
83
87
  const handlePress = React.useCallback(
84
88
  (item, index) => {
@@ -90,6 +94,27 @@ export function VerticalMenu(rootProps) {
90
94
  [onChange, onChangeIndex]
91
95
  )
92
96
 
97
+ return (
98
+ <View className="neko-vertical-menu" gap={gap} width="100%" {...props}>
99
+ <List
100
+ data={items}
101
+ keyExtractor={(item, index) => item.key || index}
102
+ divider={withDivider}
103
+ renderItem={({ item, index }) => (
104
+ <Item
105
+ key={item.key || index}
106
+ item={item}
107
+ handlePress={handlePress}
108
+ color={color}
109
+ sizeCode={sizeCode}
110
+ index={index}
111
+ {...props}
112
+ />
113
+ )}
114
+ />
115
+ </View>
116
+ )
117
+
93
118
  return (
94
119
  <View className="neko-vertical-menu" gap={gap} width="100%" {...props}>
95
120
  {items.map((item, index) => (
@@ -1,7 +1,9 @@
1
+ import dayjs from 'dayjs'
1
2
  import React from 'react'
2
3
 
3
4
  export function useCalendarDays(currentMonth) {
4
5
  return React.useMemo(() => {
6
+ if (!currentMonth?.isValid?.()) currentMonth = dayjs()
5
7
  const startWeekday = currentMonth.startOf('month').day()
6
8
  const daysInMonth = currentMonth.daysInMonth()
7
9
 
@@ -16,7 +16,7 @@ export function useAlerter() {
16
16
  footer: !hideClose && (
17
17
  <Button sm label={closeLabel || 'Close'} outline color="text_op40" onPress={onClose} fullW />
18
18
  ),
19
- footerProps: { borderT: false },
19
+ footerProps: { borderT: false, paddingV: 'md' },
20
20
  width: width || 350,
21
21
  }))
22
22
  }
@@ -12,7 +12,7 @@ function Footer({ cancelLabel, confirmLabel, onConfirm, type, onClose }) {
12
12
  const color = RESULT_TYPES[type]?.color || 'primary'
13
13
 
14
14
  return (
15
- <View row gap="sm" centerV>
15
+ <View row gap="xs" centerV>
16
16
  <Button sm label={cancelLabel || 'Cancel'} outline color="text_op40" onPress={onClose} flex disabled={loading} />
17
17
  <Button
18
18
  disabled={loading}
@@ -55,7 +55,7 @@ export function useConfirmer() {
55
55
  onClose={onClose}
56
56
  />
57
57
  ),
58
- footerProps: { borderT: false },
58
+ footerProps: { borderT: false, paddingV: 'md' },
59
59
  width: width || 350,
60
60
  }))
61
61
  }
@@ -0,0 +1,6 @@
1
+ import { LazyRender } from './LazyRender'
2
+
3
+ export function ConditionalLazyRender({ children, ...props }) {
4
+ if (!props.delay && !props.whenVisible && !props.destroyOffScreen) return children
5
+ return <LazyRender {...props}>{children}</LazyRender>
6
+ }