@neko-os/ui 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/abstractions/KeyboardDismissView.js +3 -0
  2. package/dist/abstractions/KeyboardDismissView.native.js +9 -0
  3. package/dist/components/actions/ClearLink.js +6 -0
  4. package/dist/components/actions/FloatingMenu.js +1 -1
  5. package/dist/components/calendar/CalendarNav.js +6 -6
  6. package/dist/components/carousel/Carousel.js +48 -0
  7. package/dist/components/carousel/CarouselArrows.js +40 -0
  8. package/dist/components/carousel/CarouselArrows.native.js +40 -0
  9. package/dist/components/carousel/CarouselDots.js +32 -0
  10. package/dist/components/carousel/CarouselDots.native.js +36 -0
  11. package/dist/components/carousel/CarouselHandler.js +86 -0
  12. package/dist/components/carousel/CarouselSlider.js +124 -0
  13. package/dist/components/carousel/CarouselSlider.native.js +110 -0
  14. package/dist/components/carousel/InfiniteCarousel.js +50 -0
  15. package/dist/components/carousel/index.js +6 -0
  16. package/dist/components/form/Form.js +5 -3
  17. package/dist/components/index.js +3 -1
  18. package/dist/components/inputs/DateInput.js +7 -4
  19. package/dist/components/inputs/InputWrapper.js +1 -2
  20. package/dist/components/inputs/TextInput.js +7 -6
  21. package/dist/components/inputs/datePicker/DayPicker.js +65 -23
  22. package/dist/components/inputs/datePicker/MonthPicker.js +51 -27
  23. package/dist/components/inputs/datePicker/QuarterPicker.js +52 -28
  24. package/dist/components/inputs/datePicker/WeekPicker.js +59 -24
  25. package/dist/components/inputs/datePicker/YearPicker.js +59 -35
  26. package/dist/components/keyboard/KeyboardDismissButton.js +3 -0
  27. package/dist/components/keyboard/KeyboardDismissButton.native.js +38 -0
  28. package/dist/components/keyboard/index.js +1 -0
  29. package/dist/components/modals/bottomDrawer/native/BottomDrawer.js +28 -7
  30. package/dist/components/presentation/LabelValue.js +1 -1
  31. package/dist/components/presentation/Result.js +11 -3
  32. package/dist/components/structure/KeyboardAvoidingView.js +9 -2
  33. package/dist/components/theme/ThemePicker.js +7 -12
  34. package/dist/components/theme/ThemeThumb.js +1 -1
  35. package/dist/theme/ThemeHandler.js +31 -3
  36. package/package.json +1 -1
  37. package/src/abstractions/KeyboardDismissView.js +3 -0
  38. package/src/abstractions/KeyboardDismissView.native.js +9 -0
  39. package/src/components/actions/ClearLink.js +6 -0
  40. package/src/components/actions/FloatingMenu.js +1 -1
  41. package/src/components/calendar/CalendarNav.js +6 -6
  42. package/src/components/carousel/Carousel.js +48 -0
  43. package/src/components/carousel/CarouselArrows.js +40 -0
  44. package/src/components/carousel/CarouselArrows.native.js +40 -0
  45. package/src/components/carousel/CarouselDots.js +32 -0
  46. package/src/components/carousel/CarouselDots.native.js +36 -0
  47. package/src/components/carousel/CarouselHandler.js +86 -0
  48. package/src/components/carousel/CarouselSlider.js +124 -0
  49. package/src/components/carousel/CarouselSlider.native.js +110 -0
  50. package/src/components/carousel/InfiniteCarousel.js +50 -0
  51. package/src/components/carousel/index.js +6 -0
  52. package/src/components/form/Form.js +2 -0
  53. package/src/components/index.js +2 -0
  54. package/src/components/inputs/DateInput.js +4 -1
  55. package/src/components/inputs/InputWrapper.js +1 -2
  56. package/src/components/inputs/TextInput.js +5 -4
  57. package/src/components/inputs/datePicker/DayPicker.js +63 -21
  58. package/src/components/inputs/datePicker/MonthPicker.js +50 -26
  59. package/src/components/inputs/datePicker/QuarterPicker.js +50 -26
  60. package/src/components/inputs/datePicker/WeekPicker.js +57 -22
  61. package/src/components/inputs/datePicker/YearPicker.js +58 -34
  62. package/src/components/keyboard/KeyboardDismissButton.js +3 -0
  63. package/src/components/keyboard/KeyboardDismissButton.native.js +38 -0
  64. package/src/components/keyboard/index.js +1 -0
  65. package/src/components/modals/bottomDrawer/native/BottomDrawer.js +27 -6
  66. package/src/components/presentation/LabelValue.js +1 -1
  67. package/src/components/presentation/Result.js +10 -2
  68. package/src/components/structure/KeyboardAvoidingView.js +9 -2
  69. package/src/components/theme/ThemePicker.js +8 -13
  70. package/src/components/theme/ThemeThumb.js +1 -1
  71. package/src/theme/ThemeHandler.js +31 -3
@@ -0,0 +1 @@
1
+ export * from './KeyboardDismissButton'
@@ -4,6 +4,8 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'
4
4
  import Animated, {
5
5
  useSharedValue,
6
6
  useAnimatedStyle,
7
+ useAnimatedKeyboard,
8
+ KeyboardState,
7
9
  withSpring,
8
10
  runOnJS,
9
11
  } from 'react-native-reanimated'
@@ -27,6 +29,7 @@ function InnerContent({
27
29
  enableOverScroll = true,
28
30
  enableHandlePanningGesture = true,
29
31
  enableContentPanningGesture = true,
32
+ keyboardBehavior = 'interactive',
30
33
  animationConfig = {
31
34
  damping: 50,
32
35
  stiffness: 500,
@@ -44,6 +47,7 @@ function InnerContent({
44
47
  const bottomInset = useSafeArea ? insets.bottom : 0
45
48
 
46
49
  const colors = useColors()
50
+ const keyboard = useAnimatedKeyboard()
47
51
 
48
52
  const translateY = useSharedValue(SCREEN_HEIGHT)
49
53
  const snapIndex = useSharedValue(0)
@@ -122,11 +126,9 @@ function InnerContent({
122
126
  const currentPosition = SCREEN_HEIGHT - translateY.value
123
127
  const shouldClose =
124
128
  !!handleClose &&
125
- (
126
- velocityY.value > 1500 ||
129
+ (velocityY.value > 1500 ||
127
130
  (velocityY.value > 800 && currentPosition < minSnapPoint) ||
128
- currentPosition < minSnapPoint * 0.35
129
- )
131
+ currentPosition < minSnapPoint * 0.35)
130
132
 
131
133
  if (shouldClose) {
132
134
  runOnJS(handleClose)()
@@ -148,10 +150,28 @@ function InnerContent({
148
150
  handleClose,
149
151
  ])
150
152
 
153
+ const topInset = insets.top
151
154
  const animatedSheetStyle = useAnimatedStyle(() => {
152
- const currentHeight = SCREEN_HEIGHT - translateY.value
155
+ let kbShift = 0
156
+
157
+ const kbVisible = keyboard.state.value === KeyboardState.OPEN || keyboard.state.value === KeyboardState.OPENING
158
+ if (keyboardBehavior !== 'none' && kbVisible) {
159
+ const kbHeight = keyboard.height.value
160
+
161
+ if (keyboardBehavior === 'interactive') {
162
+ // Shift up by keyboard height, but don't go above safe area
163
+ const maxShift = Math.max(0, translateY.value - topInset)
164
+ kbShift = Math.min(kbHeight, maxShift)
165
+ } else if (keyboardBehavior === 'extend') {
166
+ // Snap to fill available space above keyboard
167
+ kbShift = Math.max(0, translateY.value - topInset)
168
+ }
169
+ }
170
+
171
+ const adjustedY = translateY.value - kbShift
172
+ const currentHeight = SCREEN_HEIGHT - adjustedY
153
173
  return {
154
- transform: [{ translateY: translateY.value }],
174
+ transform: [{ translateY: adjustedY }],
155
175
  maxHeight: currentHeight,
156
176
  }
157
177
  })
@@ -200,6 +220,7 @@ function InnerContent({
200
220
  marginR="auto"
201
221
  fullW
202
222
  {...props}
223
+ minH={minSnapPoint}
203
224
  >
204
225
  <DrawerHandle hide={hideHandle} />
205
226
  <View flex {...contentProps}>
@@ -18,7 +18,7 @@ const DEFAULT_PROPS = ([{ sizeCode, color }, { vertical, spread }]) => {
18
18
  labelProps: {
19
19
  size: moveScale(sizeCode, !vertical ? 0 : -2),
20
20
  moveIconSizeScale: !vertical ? -1 : -2,
21
- color: color || 'text3',
21
+ color: color || 'text2',
22
22
  },
23
23
  valueProps: {
24
24
  size: sizeCode,
@@ -2,6 +2,7 @@ import { Divider } from '../helpers/Separator'
2
2
  import { Icon } from './Icon'
3
3
  import { Text } from '../text/Text'
4
4
  import { View } from '../structure/View'
5
+ import { useResponsiveValue } from '../../responsive'
5
6
 
6
7
  export const RESULT_TYPES = {
7
8
  error: {
@@ -23,6 +24,12 @@ export const RESULT_TYPES = {
23
24
  icon: 'information-2-fill',
24
25
  color: 'blue',
25
26
  },
27
+
28
+ empty: {
29
+ icon: 'inbox-line',
30
+ color: 'text4',
31
+ opacity: 0.7,
32
+ },
26
33
  }
27
34
 
28
35
  export function Result({
@@ -41,12 +48,13 @@ export function Result({
41
48
  const typeProps = RESULT_TYPES[type] || {}
42
49
  icon = icon || typeProps.icon
43
50
  iconColor = iconColor || typeProps.color || 'primary'
51
+ const size = useResponsiveValue({ lgu: 'h4', df: 'h5' })
44
52
 
45
53
  return (
46
- <View className="neko-result" center padding="lg" {...props}>
54
+ <View className="neko-result" center padding="lg" opacity={typeProps.opacity} {...props}>
47
55
  {!!icon && <Icon name={icon} color={iconColor} size={42} primary {...iconProps} />}
48
56
  {!!icon && <Divider height={10} />}
49
- <Text h4 center {...textProps} {...titleProps}>
57
+ <Text size={size} center color="text2" {...textProps} {...titleProps}>
50
58
  {title}
51
59
  </Text>
52
60
  {!!description && (
@@ -1,6 +1,7 @@
1
1
  import { pipe } from 'ramda'
2
2
 
3
3
  import { AbsKeyboardAvoidingView } from '../../abstractions/KeyboardAvoidingView'
4
+ import { AbsKeyboardDismissView } from '../../abstractions/KeyboardDismissView'
4
5
  import { Platform } from '../../abstractions/Platform'
5
6
  import { useSafeAreaInsets } from '../../abstractions/helpers/useSafeAreaInsets'
6
7
  import { useAnimationModifier } from '../../modifiers/animation'
@@ -19,7 +20,7 @@ import { useSizeModifier } from '../../modifiers/size'
19
20
  import { useStateModifier } from '../../modifiers/state'
20
21
  import { useThemeComponentModifier } from '../../modifiers/themeComponent'
21
22
 
22
- export function KeyboardAvoidingView({ children, keyboardVerticalOffset = 0, ...rootProps }) {
23
+ export function KeyboardAvoidingView({ children, keyboardVerticalOffset = 0, dismissOnTap = true, ...rootProps }) {
23
24
  const { bottom } = useSafeAreaInsets()
24
25
 
25
26
  const [_, props] = pipe(
@@ -46,7 +47,13 @@ export function KeyboardAvoidingView({ children, keyboardVerticalOffset = 0, ...
46
47
  keyboardVerticalOffset={keyboardVerticalOffset + bottom}
47
48
  {...props}
48
49
  >
49
- {children}
50
+ {dismissOnTap ? (
51
+ <AbsKeyboardDismissView style={{ flex: 1 }}>
52
+ {children}
53
+ </AbsKeyboardDismissView>
54
+ ) : (
55
+ children
56
+ )}
50
57
  </AbsKeyboardAvoidingView>
51
58
  )
52
59
  }
@@ -1,25 +1,20 @@
1
- import { mapObjIndexed, mergeDeepRight, values, pipe, filter } from 'ramda'
1
+ import { mapObjIndexed, values, pipe, reject, propEq } from 'ramda'
2
2
 
3
- import { DEFAULT_THEMES, useThemeHandler } from '../../theme'
3
+ import { useAllThemes, useThemeHandler } from '../../theme'
4
4
  import { IconLabel } from '../presentation'
5
5
  import { Link } from '../actions'
6
6
  import { Picker } from '../inputs'
7
7
  import { ThemeThumb } from './ThemeThumb'
8
8
 
9
- export function ThemePicker({ onChange, onlyKeys, hideKeys }) {
10
- const { activeThemeKey, themes, onChangeTheme } = useThemeHandler()
9
+ export function ThemePicker({ onChange }) {
10
+ const { activeThemeKey, onChangeTheme } = useThemeHandler()
11
+ const allThemes = useAllThemes()
11
12
 
12
- let options = pipe(
13
- mergeDeepRight(DEFAULT_THEMES),
13
+ const options = pipe(
14
14
  mapObjIndexed((obj, key) => ({ ...obj, value: key, key })),
15
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)
16
+ reject(propEq('_all', 'value'))
17
+ )(allThemes)
23
18
 
24
19
  return (
25
20
  <Picker
@@ -4,7 +4,7 @@ import { useResponsiveValue } from '../../responsive'
4
4
  import { useThemeHandler } from '../../theme'
5
5
 
6
6
  export function ThemeThumb({ value }) {
7
- const { themes } = useThemeHandler()
7
+ const { rawThemesParam: themes } = useThemeHandler()
8
8
  const { colors, label } = useFormattedTheme(themes, value)
9
9
  const isMobile = useResponsiveValue({ smd: true, df: false })
10
10
 
@@ -1,7 +1,8 @@
1
- import { mergeDeepRight } from 'ramda'
1
+ import { keys, mergeDeepRight, omit, pick, pickBy } from 'ramda'
2
2
  import React from 'react'
3
3
 
4
4
  import { DEFAULT_LIGHT_THEME } from './default/lightTheme'
5
+ import { DEFAULT_THEMES } from './default/themes'
5
6
  import { getThemeValue } from './helpers/relatedScales'
6
7
  import { useFormattedTheme } from './format/formatTheme'
7
8
 
@@ -52,8 +53,33 @@ export function useMergeThemeComponent(name, props) {
52
53
  const themeProps = useThemeComponent(name)
53
54
  return mergeDeepRight(themeProps, props)
54
55
  }
56
+ export function useAllThemes() {
57
+ const { disableDefaultThemes, enableOnlyThemes, rawThemesParam } = useThemeHandler()
58
+ const themes = rawThemesParam || {}
59
+ const themesParamKeys = keys(themes)
55
60
 
56
- export function ThemeHandler({ breakpoints, themes, initTheme, onChangeTheme, children }) {
61
+ let allThemes = mergeDeepRight(DEFAULT_THEMES, themes)
62
+ if (disableDefaultThemes === true) {
63
+ allThemes = pickBy((_, key) => themesParamKeys.includes(key), allThemes)
64
+ } else if (disableDefaultThemes?.length) {
65
+ allThemes = omit(disableDefaultThemes, allThemes)
66
+ }
67
+ if (enableOnlyThemes?.length) {
68
+ allThemes = pick(enableOnlyThemes, allThemes)
69
+ }
70
+
71
+ return allThemes
72
+ }
73
+
74
+ export function ThemeHandler({
75
+ breakpoints,
76
+ themes,
77
+ initTheme,
78
+ onChangeTheme,
79
+ children,
80
+ disableDefaultThemes,
81
+ enableOnlyThemes,
82
+ }) {
57
83
  const [themePickerOpen, setThemePickerOpen] = React.useState(false)
58
84
  const openThemePicker = () => setThemePickerOpen(true)
59
85
  const [activeThemeKey, setActiveThemeKey] = React.useState(initTheme || 'light')
@@ -66,7 +92,9 @@ export function ThemeHandler({ breakpoints, themes, initTheme, onChangeTheme, ch
66
92
 
67
93
  const value = {
68
94
  theme,
69
- themes,
95
+ rawThemesParam: themes,
96
+ disableDefaultThemes,
97
+ enableOnlyThemes,
70
98
  activeThemeKey,
71
99
  toggleTheme,
72
100
  themePickerOpen,