@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
@@ -14,20 +14,19 @@ import { useCalendarDays } from '../../calendar/_helpers/calendarDays'
14
14
  export function DayPicker({ value, onChange, min, max, onCheckDisabled, ...props }) {
15
15
  if (!!value) value = dayjs(value)
16
16
  const [localValue, setLocalValue] = React.useState(value)
17
+ const [currentMonth, setCurrentMonth] = React.useState(() => dayjs(value || undefined).startOf('month'))
18
+ value = value === undefined ? localValue : value
17
19
 
18
20
  React.useEffect(() => {
19
21
  setLocalValue(value)
20
- }, [value])
21
-
22
- value = value === undefined ? localValue : value
22
+ if (value?.isValid?.()) setCurrentMonth(value.startOf('month'))
23
+ }, [value?.day?.(), value?.month?.(), value?.year?.()])
23
24
 
24
25
  const handleChange = (v) => {
25
26
  setLocalValue(v)
26
27
  onChange?.(v)
27
28
  }
28
29
 
29
- const [currentMonth, setCurrentMonth] = React.useState(() => dayjs(value).startOf('month'))
30
-
31
30
  const { cells } = useCalendarDays(currentMonth)
32
31
 
33
32
  return (
@@ -14,10 +14,12 @@ const months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
14
14
 
15
15
  export function MonthPicker({ value, onChange, min, max, onCheckDisabled, ...props }) {
16
16
  const [localValue, setLocalValue] = React.useState(value)
17
+ const [currentYear, setCurrentYear] = React.useState(() => dayjs(value || undefined).startOf('year'))
17
18
  value = value === undefined ? localValue : value
18
19
 
19
20
  React.useEffect(() => {
20
21
  setLocalValue(value)
22
+ if (value?.isValid?.()) setCurrentYear(value.startOf('year'))
21
23
  }, [value?.month?.(), value?.year?.()])
22
24
 
23
25
  const handleChange = (v) => {
@@ -26,8 +28,6 @@ export function MonthPicker({ value, onChange, min, max, onCheckDisabled, ...pro
26
28
  onChange?.(newValue)
27
29
  }
28
30
 
29
- const [currentYear, setCurrentYear] = React.useState(() => dayjs(value).startOf('year'))
30
-
31
31
  return (
32
32
  <View className="neko-day-picker" width={275} {...props}>
33
33
  <CalendarNav value={currentYear} onChange={setCurrentYear} level="year" />
@@ -17,10 +17,12 @@ const quarters = [1, 2, 3, 4]
17
17
 
18
18
  export function QuarterPicker({ value, onChange, min, max, onCheckDisabled, ...props }) {
19
19
  const [localValue, setLocalValue] = React.useState(value)
20
+ const [currentYear, setCurrentYear] = React.useState(() => dayjs(value || undefined).startOf('year'))
20
21
  value = value === undefined ? localValue : value
21
22
 
22
23
  React.useEffect(() => {
23
24
  setLocalValue(value)
25
+ if (value?.isValid?.()) setCurrentYear(value.startOf('year'))
24
26
  }, [value?.quarter?.(), value?.year?.()])
25
27
 
26
28
  const handleChange = (v) => {
@@ -29,8 +31,6 @@ export function QuarterPicker({ value, onChange, min, max, onCheckDisabled, ...p
29
31
  onChange?.(newValue)
30
32
  }
31
33
 
32
- const [currentYear, setCurrentYear] = React.useState(() => dayjs(value).startOf('year'))
33
-
34
34
  return (
35
35
  <View className="neko-day-picker" width={275} {...props}>
36
36
  <CalendarNav value={currentYear} onChange={setCurrentYear} level="year" />
@@ -14,10 +14,12 @@ import { useCalendarDays } from '../../calendar/_helpers/calendarDays'
14
14
 
15
15
  export function WeekPicker({ value, onChange, min, max, onCheckDisabled, ...props }) {
16
16
  const [localValue, setLocalValue] = React.useState(value)
17
+ const [currentMonth, setCurrentMonth] = React.useState(() => dayjs(value || undefined).startOf('month'))
17
18
  value = value === undefined ? localValue : value
18
19
 
19
20
  React.useEffect(() => {
20
21
  setLocalValue(value)
22
+ if (value?.isValid?.()) setCurrentMonth(value.startOf('month'))
21
23
  }, [value?.day?.(), value?.month?.(), value?.year?.()])
22
24
 
23
25
  const handleChange = (v) => {
@@ -26,8 +28,6 @@ export function WeekPicker({ value, onChange, min, max, onCheckDisabled, ...prop
26
28
  onChange?.(newValue)
27
29
  }
28
30
 
29
- const [currentMonth, setCurrentMonth] = React.useState(() => dayjs(value).startOf('month'))
30
-
31
31
  const { cells } = useCalendarDays(currentMonth)
32
32
  const weeks = splitEvery(7, cells)
33
33
 
@@ -11,12 +11,21 @@ import { Text } from '../../text/Text'
11
11
  import { View } from '../../structure/View'
12
12
  import { isDateDisabled } from '../../calendar/_helpers/dateDisabled'
13
13
 
14
+ function getDecade(value) {
15
+ const year = dayjs(value || undefined).year()
16
+ const decadeStartYear = Math.floor(year / 10) * 10
17
+ return dayjs().year(decadeStartYear).startOf('year')
18
+ }
19
+
14
20
  export function YearPicker({ value, onChange, min, max, onCheckDisabled, ...props }) {
15
21
  const [localValue, setLocalValue] = React.useState(value)
22
+ const [currentDecade, setCurrentDecade] = React.useState(() => getDecade(value))
23
+
16
24
  value = value === undefined ? localValue : value
17
25
 
18
26
  React.useEffect(() => {
19
27
  setLocalValue(value)
28
+ if (value?.isValid?.()) setCurrentDecade(getDecade(value))
20
29
  }, [value?.year?.()])
21
30
 
22
31
  const handleChange = (v) => {
@@ -25,12 +34,6 @@ export function YearPicker({ value, onChange, min, max, onCheckDisabled, ...prop
25
34
  onChange?.(newValue)
26
35
  }
27
36
 
28
- const [currentDecade, setCurrentDecade] = React.useState(() => {
29
- const year = dayjs(value).year()
30
- const decadeStartYear = Math.floor(year / 10) * 10
31
- return dayjs().year(decadeStartYear).startOf('year')
32
- })
33
-
34
37
  const years = range(currentDecade.year(), currentDecade.year() + 10)
35
38
 
36
39
  return (
@@ -3,8 +3,12 @@ export * from './Radio'
3
3
  export * from './Switch'
4
4
  export * from './InputWrapper'
5
5
  export * from './TextInput'
6
+ export * from './NumberInput'
6
7
  export * from './LinkInput'
7
8
  export * from './MaskInput'
8
9
  export * from './DateInput'
9
10
  export * from './datePicker/DatePicker'
10
11
  export * from './Picker'
12
+ export * from './Select'
13
+ export * from './RateInput'
14
+ export * from './SegmentedPicker'
@@ -32,7 +32,7 @@ export function Layout({ children, ...rootProps }) {
32
32
 
33
33
  return (
34
34
  <LayoutContext.Provider value={value}>
35
- <View className="neko-layout" bg="bg" flex relative {...rootProps} ref={layoutRef}>
35
+ <View className="neko-layout" bg="mainBG" flex relative {...rootProps} ref={layoutRef}>
36
36
  {children}
37
37
  </View>
38
38
  </LayoutContext.Provider>
@@ -0,0 +1,91 @@
1
+ import { pipe } from 'ramda'
2
+ import React from 'react'
3
+
4
+ import { AbsFlatList } from '../../abstractions/FlatList'
5
+ import { AbsStaticList } from '../../abstractions/StaticList'
6
+ import { ConditionalLazyRender, Divider } from '../helpers'
7
+ import { useAnimationModifier } from '../../modifiers/animation'
8
+ import { useBackgroundModifier } from '../../modifiers/background'
9
+ import { useBorderModifier } from '../../modifiers/border'
10
+ import { useDefaultModifier } from '../../modifiers/default'
11
+ import { useDisplayModifier } from '../../modifiers/display'
12
+ import { useFlexModifier } from '../../modifiers/flex'
13
+ import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
14
+ import { useMarginModifier } from '../../modifiers/margin'
15
+ import { useOverflowModifier } from '../../modifiers/overflow'
16
+ import { usePaddingModifier } from '../../modifiers/padding'
17
+ import { usePositionModifier } from '../../modifiers/position'
18
+ import { useResponsiveValue } from '../../responsive'
19
+ import { useShadowModifier } from '../../modifiers/shadow'
20
+ import { useSizeModifier } from '../../modifiers/size'
21
+ import { useStateModifier } from '../../modifiers/state'
22
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
23
+
24
+ const DEFAULT_PROPS = ([_, { horizontal }]) => {
25
+ const overflowKey = horizontal ? 'scrollX' : 'scrollY'
26
+
27
+ return {
28
+ [overflowKey]: true,
29
+ row: !!horizontal,
30
+ }
31
+ }
32
+
33
+ export function FlatList({ children, ...rootProps }) {
34
+ const [_, formattedProps] = pipe(
35
+ useThemeComponentModifier('FlatList'),
36
+ useDefaultModifier(DEFAULT_PROPS),
37
+ useFlexWrapperModifier,
38
+ useDisplayModifier,
39
+ useAnimationModifier,
40
+ useStateModifier,
41
+ useSizeModifier,
42
+ usePositionModifier,
43
+ useOverflowModifier,
44
+ usePaddingModifier,
45
+ useMarginModifier,
46
+ useFlexModifier,
47
+ useBackgroundModifier,
48
+ useBorderModifier,
49
+ useShadowModifier
50
+ )([{}, rootProps])
51
+
52
+ let {
53
+ divider,
54
+ dividerColor,
55
+ dividerProps,
56
+ renderSeparator,
57
+ renderItem,
58
+ lazy,
59
+ onlyOnScreen,
60
+ itemMinHeight,
61
+ ...props
62
+ } = formattedProps
63
+ const noScroll = useResponsiveValue(rootProps.noScroll)
64
+ const Wrapper = noScroll ? AbsStaticList : AbsFlatList
65
+
66
+ const formattedRenderItem = React.useCallback(
67
+ (...params) => (
68
+ <ConditionalLazyRender
69
+ whenVisible={lazy || onlyOnScreen}
70
+ destroyOffScreen={onlyOnScreen}
71
+ minHeight={itemMinHeight}
72
+ >
73
+ {renderItem?.(...params)}
74
+ </ConditionalLazyRender>
75
+ ),
76
+ [renderItem]
77
+ )
78
+
79
+ if (!renderSeparator && !!divider) {
80
+ if (divider === true) divider = 1
81
+ renderSeparator = () => <Divider line={divider} height={divider} color={dividerColor} {...dividerProps} />
82
+ }
83
+
84
+ return (
85
+ <Wrapper className="neko-flat-list" renderSeparator={renderSeparator} renderItem={formattedRenderItem} {...props}>
86
+ {children}
87
+ </Wrapper>
88
+ )
89
+ }
90
+
91
+ export const List = (props) => <FlatList noScroll {...props} />
@@ -1 +1,2 @@
1
1
  export * from './ScrollView'
2
+ export * from './FlatList'
@@ -0,0 +1,58 @@
1
+ import { pipe, range, is } from 'ramda'
2
+
3
+ import { Icon } from '../presentation'
4
+ import { View } from '../structure/View'
5
+ import { useColorConverter } from '../../modifiers/colorConverter'
6
+ import { useDefaultModifier } from '../../modifiers/default'
7
+ import { useSizeConverter } from '../../modifiers/sizeConverter'
8
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
9
+
10
+ const DEFAULT_PROPS = {
11
+ color: 'primary',
12
+ inactiveColor: 'text4_op50',
13
+ max: 5,
14
+ icon: 'star-fill',
15
+ }
16
+
17
+ export function Rate({ value, ...rootProps }) {
18
+ let [{ size, sizeCode, color }, formattedProps] = pipe(
19
+ useColorConverter('primary'),
20
+ useSizeConverter('icons', 'md'),
21
+ useThemeComponentModifier('Rate'),
22
+ useDefaultModifier(DEFAULT_PROPS)
23
+ )([{}, rootProps])
24
+
25
+ const { icon, max, inactiveColor, tag, ...props } = formattedProps
26
+
27
+ return (
28
+ <View className="neko-rate" row gap="xxs" centerV minHeight={sizeCode} {...props}>
29
+ {range(1, max + 1).map((i) => {
30
+ const active = value >= i
31
+ const partial = getDecimalOrEdge(value, i)
32
+
33
+ let finalIcon = icon
34
+ if (is(Function, icon)) finalIcon = icon?.({ value, optionValue: i, active })
35
+
36
+ let finalColor = color
37
+ if (is(Function, color)) finalColor = color?.({ value, optionValue: i, active })
38
+
39
+ return (
40
+ <View center key={i} relative>
41
+ <Icon name={finalIcon} size={sizeCode} color={inactiveColor} />
42
+ {!!partial && (
43
+ <View absolute overflow="hidden" left={0} width={100 * partial + '%'}>
44
+ <Icon name={finalIcon} size={sizeCode} color={finalColor} />
45
+ </View>
46
+ )}
47
+ </View>
48
+ )
49
+ })}
50
+ </View>
51
+ )
52
+ }
53
+
54
+ function getDecimalOrEdge(value, i) {
55
+ if (value >= i) return 1
56
+ if (value < i - 1) return 0
57
+ return value - Math.floor(value)
58
+ }
@@ -0,0 +1,35 @@
1
+ import { pipe } from 'ramda'
2
+
3
+ import { Tag } from './Tag'
4
+ import { moveScale } from '../../theme/helpers/sizeScale'
5
+ import { useColorConverter } from '../../modifiers/colorConverter'
6
+ import { useDefaultModifier } from '../../modifiers/default'
7
+ import { useSizeConverter } from '../../modifiers/sizeConverter'
8
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
9
+
10
+ const DEFAULT_PROPS = {
11
+ icon: 'star-fill', //
12
+ // outline: false,
13
+ }
14
+
15
+ export function RateTag({ value, ...rootProps }) {
16
+ let [{ size, sizeCode, color }, formattedProps] = pipe(
17
+ useColorConverter('primary'),
18
+ useSizeConverter('icons', 'md'),
19
+ useThemeComponentModifier('RateTag'),
20
+ useDefaultModifier(DEFAULT_PROPS)
21
+ )([{}, rootProps])
22
+
23
+ const { icon, ...props } = formattedProps
24
+
25
+ return (
26
+ <Tag
27
+ icon={icon}
28
+ label={value}
29
+ color={color}
30
+ textProps={{ size: moveScale(sizeCode, -1) }}
31
+ gap={moveScale(sizeCode, -3)}
32
+ {...props}
33
+ />
34
+ )
35
+ }
@@ -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 h3 {...textProps} {...titleProps}>
49
+ <Text h4 {...textProps} {...titleProps}>
50
50
  {title}
51
51
  </Text>
52
52
  {!!description && (
53
- <Text text3 sm {...textProps} {...descriptionProps}>
53
+ <Text text3 sm marginT="sm" {...textProps} {...descriptionProps}>
54
54
  {description}
55
55
  </Text>
56
56
  )}
@@ -21,6 +21,7 @@ export function Tooltip(rootProps) {
21
21
  return (
22
22
  <Popover
23
23
  className="neko-tooltip"
24
+ padding="xs"
24
25
  {...props}
25
26
  content={
26
27
  <IconLabel
@@ -10,3 +10,5 @@ export * from './AvatarLabel'
10
10
  export * from './Image'
11
11
  export * from './ImageBackground'
12
12
  export * from './LabelValue'
13
+ export * from './Rate'
14
+ export * from './RateTag'
@@ -18,7 +18,16 @@ export function LoadingView({ active, children, size, color, replaceChildren, no
18
18
  return (
19
19
  <View className="neko-loading-view" relative {...props}>
20
20
  {children}
21
- <View className="neko-laoding-view-overlay" bg="bg_op90" absolute top={0} left={0} right={0} bottom={0} center>
21
+ <View
22
+ className="neko-laoding-view-overlay"
23
+ bg="mainBG_op90"
24
+ absolute
25
+ top={0}
26
+ left={0}
27
+ right={0}
28
+ bottom={0}
29
+ center
30
+ >
22
31
  {loader}
23
32
  </View>
24
33
  </View>
@@ -43,7 +43,7 @@ export function Accordion({ children, title, open, onChange, ...rootProps }) {
43
43
  row
44
44
  gap={moveScale(sizeCode, -2)}
45
45
  borderB={open ? props.border || true : open}
46
- borderColor={props.borderColor || 'bg'}
46
+ borderColor={props.borderColor || 'divider_op40'}
47
47
  centerV
48
48
  {...headerProps}
49
49
  onPress={toggle}
@@ -2,12 +2,16 @@ import { pipe } from 'ramda'
2
2
  import React from 'react'
3
3
 
4
4
  import { AbsView } from '../../abstractions/View'
5
+ import { useBackgroundModifier } from '../../modifiers/background'
6
+ import { useBorderModifier } from '../../modifiers/border'
5
7
  import { useFlexModifier } from '../../modifiers/flex'
6
8
  import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
7
9
  import { useGridModifier } from '../../modifiers/grid'
8
10
  import { useMarginModifier } from '../../modifiers/margin'
11
+ import { usePaddingModifier } from '../../modifiers/padding'
9
12
  import { usePositionModifier } from '../../modifiers/position'
10
13
  import { useResponsiveConverter } from '../../modifiers/responsiveConverter'
14
+ import { useShadowModifier } from '../../modifiers/shadow'
11
15
  import { useSizeModifier } from '../../modifiers/size'
12
16
  import { useThemeComponentModifier } from '../../modifiers/themeComponent'
13
17
 
@@ -20,7 +24,11 @@ export function Row({ children, ...rootProps }) {
20
24
  usePositionModifier,
21
25
  useFlexWrapperModifier,
22
26
  useFlexModifier,
23
- useMarginModifier
27
+ useMarginModifier,
28
+ usePaddingModifier,
29
+ useBackgroundModifier,
30
+ useBorderModifier,
31
+ useShadowModifier
24
32
  )([{}, rootProps])
25
33
 
26
34
  // Memoiza os children clonados para evitar recriação se childPaddingProps não mudar
@@ -0,0 +1,51 @@
1
+ import { pipe } from 'ramda'
2
+ import React from 'react'
3
+
4
+ import { View } from './View'
5
+ import { useDefaultModifier } from '../../modifiers/default'
6
+ import { useSizeConverter } from '../../modifiers/sizeConverter'
7
+ import { useThemeComponentModifier } from '../../modifiers/themeComponent'
8
+
9
+ const DEFAULT_PROPS = ([{ sizeCode }]) => ({
10
+ row: true,
11
+ justify: 'stretch',
12
+ br: sizeCode,
13
+ // overflow: 'hidden',
14
+ })
15
+
16
+ export function Segment({ children, ...rootProps }) {
17
+ const [{ sizeCode }, formattedProps] = pipe(
18
+ useSizeConverter('elementHeights', 'md'),
19
+ useThemeComponentModifier('Segment'),
20
+ useDefaultModifier(DEFAULT_PROPS)
21
+ )([{}, rootProps])
22
+
23
+ const { br, ...props } = formattedProps
24
+ const size = children?.length
25
+
26
+ return (
27
+ <View className="neko-segment" {...props}>
28
+ {React.Children.map(children, (child, index) => {
29
+ if (!React.isValidElement(child)) return child
30
+ const isFirst = index === 0
31
+ const isLast = size - 1 === index
32
+
33
+ const childProps = child.props || {}
34
+ const newProps = {
35
+ brL: br,
36
+ brR: br,
37
+ size: sizeCode,
38
+ }
39
+
40
+ if (!isLast) {
41
+ newProps.brR = 0
42
+ }
43
+ if (!isFirst) {
44
+ newProps.brL = 0
45
+ }
46
+
47
+ return React.cloneElement(child, newProps)
48
+ })}
49
+ </View>
50
+ )
51
+ }
@@ -4,6 +4,7 @@ import { AbsView } from '../../abstractions/View'
4
4
  import { useAnimationModifier } from '../../modifiers/animation'
5
5
  import { useBackgroundModifier } from '../../modifiers/background'
6
6
  import { useBorderModifier } from '../../modifiers/border'
7
+ import { useCursorModifier } from '../../modifiers/cursor'
7
8
  import { useDisplayModifier } from '../../modifiers/display'
8
9
  import { useFlexModifier } from '../../modifiers/flex'
9
10
  import { useFlexWrapperModifier } from '../../modifiers/flexWrapper'
@@ -21,6 +22,7 @@ export function View({ children, ...rootProps }) {
21
22
  useThemeComponentModifier('View'),
22
23
  useFlexWrapperModifier,
23
24
  useDisplayModifier,
25
+ useCursorModifier,
24
26
  useAnimationModifier,
25
27
  useStateModifier,
26
28
  useSizeModifier,
@@ -53,7 +53,10 @@ function InnerContent({
53
53
  const snapIndex = useSharedValue(0)
54
54
  const velocityY = useSharedValue(0)
55
55
 
56
- const normalizedSnapPoints = React.useMemo(() => normalizeSnapPoints(snapPoints, SCREEN_HEIGHT), [snapPoints])
56
+ const normalizedSnapPoints = React.useMemo(
57
+ () => normalizeSnapPoints(snapPoints, SCREEN_HEIGHT, bottomInset),
58
+ [snapPoints, useSafeArea]
59
+ )
57
60
  const maxSnapPoint = React.useMemo(() => Math.max(...normalizedSnapPoints), [normalizedSnapPoints])
58
61
  const minSnapPoint = React.useMemo(() => Math.min(...normalizedSnapPoints), [normalizedSnapPoints])
59
62
 
@@ -189,8 +192,21 @@ function InnerContent({
189
192
 
190
193
  <DrawerProvider value={contextValue}>
191
194
  <GestureDetector gesture={panGesture}>
192
- <Animated.View style={[styles.container, { height: SCREEN_HEIGHT }, animatedSheetStyle]}>
193
- <View flex bg="overlayBG" shadow paddingB={useSafeArea && bottomInset} borderRadiusT="xxxl" {...props}>
195
+ <Animated.View
196
+ style={[styles.container, { height: SCREEN_HEIGHT }, animatedSheetStyle]}
197
+ pointerEvents="box-none"
198
+ >
199
+ <View
200
+ flex
201
+ bg="overlayBG"
202
+ shadow
203
+ paddingB={useSafeArea && bottomInset}
204
+ borderRadiusT="xxxl"
205
+ marginL="auto"
206
+ marginR="auto"
207
+ fullW
208
+ {...props}
209
+ >
194
210
  <DrawerHandle hide={hideHandle} />
195
211
  <View flex {...contentProps}>
196
212
  {children}
@@ -1,27 +1,32 @@
1
- export function normalizeSnapPoints(snapPoints, screenHeight) {
1
+ import { is } from 'ramda'
2
+
3
+ export function normalizeSnapPoints(snapPoints, screenHeight, bottomInset) {
2
4
  return snapPoints.map((point) => {
3
5
  if (typeof point === 'string' && point.endsWith('%')) {
4
- const percentage = parseFloat(point) / 100;
5
- return screenHeight * percentage;
6
+ const percentage = parseFloat(point) / 100
7
+ return screenHeight * percentage
8
+ }
9
+ if (is(Number, point)) {
10
+ point = point + bottomInset
6
11
  }
7
- return point;
8
- });
12
+ return point
13
+ })
9
14
  }
10
15
 
11
16
  export function findClosestSnapPoint(currentPosition, snapPoints, velocity = 0) {
12
- 'worklet';
17
+ 'worklet'
13
18
  // Reduced velocity impact for more stable snapping
14
- const velocityImpact = velocity * 0.03;
15
- const adjustedPosition = currentPosition + velocityImpact;
19
+ const velocityImpact = velocity * 0.03
20
+ const adjustedPosition = currentPosition + velocityImpact
16
21
 
17
- let closestIndex = 0;
18
- let minDistance = Math.abs(snapPoints[0] - adjustedPosition);
22
+ let closestIndex = 0
23
+ let minDistance = Math.abs(snapPoints[0] - adjustedPosition)
19
24
 
20
25
  for (let i = 1; i < snapPoints.length; i++) {
21
- const distance = Math.abs(snapPoints[i] - adjustedPosition);
26
+ const distance = Math.abs(snapPoints[i] - adjustedPosition)
22
27
  if (distance < minDistance) {
23
- minDistance = distance;
24
- closestIndex = i;
28
+ minDistance = distance
29
+ closestIndex = i
25
30
  }
26
31
  }
27
32
 
@@ -30,29 +35,31 @@ export function findClosestSnapPoint(currentPosition, snapPoints, velocity = 0)
30
35
 
31
36
  // Bias towards opening more when swiping up very fast
32
37
  if (velocity < -1500 && closestIndex < snapPoints.length - 1) {
33
- closestIndex++;
38
+ closestIndex++
34
39
  }
35
40
  // Bias towards closing when swiping down very fast
36
41
  else if (velocity > 1500 && closestIndex > 0) {
37
- closestIndex--;
42
+ closestIndex--
38
43
  }
39
44
 
40
45
  // Add hysteresis: prefer staying at current position unless moved significantly
41
46
  // This prevents accidental snap point changes
42
47
  if (snapPoints.length > 1) {
43
- const currentSnapDistance = minDistance;
48
+ const currentSnapDistance = minDistance
44
49
  // Require at least 20% of the distance between snap points to change
45
- const snapPointSpacing = Math.abs(snapPoints[Math.min(closestIndex + 1, snapPoints.length - 1)] - snapPoints[closestIndex]);
50
+ const snapPointSpacing = Math.abs(
51
+ snapPoints[Math.min(closestIndex + 1, snapPoints.length - 1)] - snapPoints[closestIndex]
52
+ )
46
53
  if (currentSnapDistance < snapPointSpacing * 0.2) {
47
54
  // Stay at current snap point unless moved significantly
48
- return closestIndex;
55
+ return closestIndex
49
56
  }
50
57
  }
51
58
 
52
- return closestIndex;
59
+ return closestIndex
53
60
  }
54
61
 
55
62
  export function clamp(value, min, max) {
56
- 'worklet';
57
- return Math.min(Math.max(value, min), max);
58
- }
63
+ 'worklet'
64
+ return Math.min(Math.max(value, min), max)
65
+ }
@@ -1,3 +1,5 @@
1
1
  import { Drawer } from '../../drawer'
2
2
 
3
- export const BottomDrawer = (props) => <Drawer height={400} {...props} />
3
+ export const BottomDrawer = ({ snapPoints, contentProps, ...props }) => {
4
+ return <Drawer height={snapPoints?.[0] || 400} contentProps={{ padding: 0, ...contentProps }} {...props} />
5
+ }
@@ -11,3 +11,4 @@ export * from './modal'
11
11
  export * from './drawer'
12
12
  export * from './bottomDrawer'
13
13
  export * from './popover/Popover'
14
+ export * from './Segment'
@@ -29,6 +29,11 @@ export const useRegisterOverlay = (opts = {}) => {
29
29
  mergeOverlay({ open: true, content, triggerRect, placement, ...options })
30
30
  }
31
31
 
32
+ const onUpdate = ({ content, options = {} }) => {
33
+ if (!overlay.open) return
34
+ mergeOverlay({ content, ...options })
35
+ }
36
+
32
37
  const onClose = () => {
33
38
  stopDelayedClosing()
34
39
  timeout.current = setTimeout(() => {
@@ -41,7 +46,7 @@ export const useRegisterOverlay = (opts = {}) => {
41
46
  !!unmountOnClose ? removeOverlay() : closeOverlay()
42
47
  }
43
48
 
44
- return { onOpen, onClose, onFastClose, stopDelayedClosing }
49
+ return { onOpen, onClose, onUpdate, onFastClose, stopDelayedClosing }
45
50
  }
46
51
 
47
52
  export function OverlayHandler({ children }) {