@neko-os/ui 0.5.0 → 0.5.1

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.
@@ -0,0 +1 @@
1
+ export * from "./Platform";
@@ -27,12 +27,20 @@ export function CarouselSlider() {var _this = this;
27
27
  var translateX = useSharedValue(0);
28
28
  var gestureStartX = useSharedValue(0);
29
29
  var prevItemsRef = React.useRef(items);
30
+ var gestureAnimatingRef = React.useRef(false);
31
+
32
+ var setGestureAnimating = React.useCallback(function (v) {
33
+ gestureAnimatingRef.current = v;
34
+ }, []);
30
35
 
31
36
  React.useEffect(function () {
32
37
  if (slideWidth > 0) {
33
38
  if (prevItemsRef.current !== items) {
34
39
  prevItemsRef.current = items;
35
40
  translateX.value = -activeIndex * slideWidth;
41
+ } else if (gestureAnimatingRef.current) {
42
+
43
+ gestureAnimatingRef.current = false;
36
44
  } else {
37
45
  translateX.value = withTiming(-activeIndex * slideWidth, { duration: 300 }, function (finished) {var _items$activeIndex;
38
46
  if (finished && afterChange) runOnJS(afterChange)(items == null ? void 0 : (_items$activeIndex = items[activeIndex]) == null ? void 0 : _items$activeIndex.key, activeIndex);
@@ -87,7 +95,10 @@ export function CarouselSlider() {var _this = this;
87
95
  }
88
96
 
89
97
  var clamped = clampIndex(targetIndex, itemsCount, loop);
90
- translateX.value = withTiming(-clamped * slideWidth, { duration: 300 });
98
+ translateX.value = withTiming(-clamped * slideWidth, { duration: 300 }, function (finished) {var _items$clamped;
99
+ if (finished && afterChange) runOnJS(afterChange)(items == null ? void 0 : (_items$clamped = items[clamped]) == null ? void 0 : _items$clamped.key, clamped);
100
+ });
101
+ runOnJS(setGestureAnimating)(true);
91
102
  runOnJS(goTo)(targetIndex);
92
103
  runOnJS(resumeAutoplay)();
93
104
  });
@@ -2,6 +2,7 @@ var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/compon
2
2
  import React from 'react';
3
3
 
4
4
  import { Icon, IconLabel } from "../presentation";
5
+ import { KeyboardDismissButton } from "../keyboard";
5
6
  import { Link } from "../actions";
6
7
  import { LinkInput } from "./LinkInput";
7
8
  import { Picker, getOptionLabel, searchOptions } from "./Picker";
@@ -134,58 +135,61 @@ export function Select(_ref2)
134
135
  maxHeight: popoverMaxHeight },
135
136
  popoverProps, {
136
137
  renderContent: function renderContent(_ref3) {var onClose = _ref3.onClose;return (
137
- _jsx(Picker, Object.assign({
138
- row: false,
139
- options: searchOptions(options, search, { labelKey: labelKey }),
140
- value: value,
141
- gap: 0,
142
- maxHeight: !useBottomDrawer && popoverMaxHeight,
143
- useFlatList: true,
144
- onlyOnScreen: true,
145
- itemMinHeight: 30,
146
- onChange: function onChange(v, option) {
147
- handleChange(v, option);
148
- if (!multiple) {
149
- setFocus(false);
150
- onClose();
151
- }
152
- } },
153
- pickerProps, {
154
- renderHeader:
155
- useBottomDrawer && useSearch ?
156
- function () {return (
157
- _jsxs(_Fragment, { children: [
158
- _jsx(View, { padding: "md", paddingB: "xs", children:
159
- _jsx(TextInput, {
160
- prefixIcon: "search-line",
161
- prefixIconColor: "text4",
162
- value: search,
163
- onChange: handleChangeSearch }
164
- ) }
165
- ),
166
- renderHeader == null ? void 0 : renderHeader()] }
167
- ));} :
168
-
169
- renderHeader,
170
-
171
- renderOption: function renderOption(_ref4) {var option = _ref4.option,selected = _ref4.selected,onChange = _ref4.onChange;return (
172
- _jsxs(Link, {
173
- row: true,
174
- paddingH: useBottomDrawer ? 'md' : 'sm',
175
- paddingV: "xs",
176
- minHeight: useBottomDrawer ? 'xl' : 'md',
177
- gap: "sm",
178
- onMouseDown: function onMouseDown(e) {return !!multiple && e.preventDefault();},
179
- onPress: onChange,
180
- centerV: true,
181
- bg: selected && 'primary_op10', children: [
182
-
183
- _jsx(View, { flex: true, row: true, children:
184
- finalRenderOption({ option: option, labelKey: labelKey, selected: selected }) }
185
- ),
186
- selected && _jsx(Icon, { name: "checkbox-circle-fill", primary: true })] }
187
- ));} })
188
-
138
+ _jsxs(_Fragment, { children: [
139
+ useBottomDrawer && useSearch && _jsx(KeyboardDismissButton, {}),
140
+ _jsx(Picker, Object.assign({
141
+ row: false,
142
+ options: searchOptions(options, search, { labelKey: labelKey }),
143
+ value: value,
144
+ gap: 0,
145
+ maxHeight: !useBottomDrawer && popoverMaxHeight,
146
+ useFlatList: true,
147
+ onlyOnScreen: true,
148
+ itemMinHeight: 30,
149
+ onChange: function onChange(v, option) {
150
+ handleChange(v, option);
151
+ if (!multiple) {
152
+ setFocus(false);
153
+ onClose();
154
+ }
155
+ } },
156
+ pickerProps, {
157
+ renderHeader:
158
+ useBottomDrawer && useSearch ?
159
+ _jsxs(_Fragment, { children: [
160
+ _jsx(View, { padding: "md", paddingB: "xs", children:
161
+ _jsx(TextInput, {
162
+ prefixIcon: "search-line",
163
+ prefixIconColor: "text4",
164
+ value: search,
165
+ onChange: handleChangeSearch }
166
+ ) }
167
+ ),
168
+ renderHeader == null ? void 0 : renderHeader()] }
169
+ ) :
170
+
171
+ renderHeader,
172
+
173
+
174
+ renderOption: function renderOption(_ref4) {var option = _ref4.option,selected = _ref4.selected,onChange = _ref4.onChange;return (
175
+ _jsxs(Link, {
176
+ row: true,
177
+ paddingH: useBottomDrawer ? 'md' : 'sm',
178
+ paddingV: "xs",
179
+ minHeight: useBottomDrawer ? 'xl' : 'md',
180
+ gap: "sm",
181
+ onMouseDown: function onMouseDown(e) {return !!multiple && e.preventDefault();},
182
+ onPress: onChange,
183
+ centerV: true,
184
+ bg: selected && 'primary_op10', children: [
185
+
186
+ _jsx(View, { flex: true, row: true, children:
187
+ finalRenderOption({ option: option, labelKey: labelKey, selected: selected }) }
188
+ ),
189
+ selected && _jsx(Icon, { name: "checkbox-circle-fill", primary: true })] }
190
+ ));} })
191
+
192
+ )] }
189
193
  ));}, children:
190
194
 
191
195
 
@@ -24,7 +24,9 @@ function fromMonthValue(v) {
24
24
  startOf('month');
25
25
  }
26
26
 
27
- function MonthDays(_ref) {var _this = this;var month = _ref.month,selectedValue = _ref.selectedValue,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
27
+ var MonthDays = React.memo(function MonthDays(_ref) {var _this = this;var monthValue = _ref.monthValue,selectedKey = _ref.selectedKey,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
28
+ var month = fromMonthValue(monthValue);
29
+ var selectedValue = selectedKey ? dayjs(selectedKey) : null;
28
30
  var _useCalendarDays = useCalendarDays(month),cells = _useCalendarDays.cells;
29
31
 
30
32
  return (
@@ -57,9 +59,9 @@ function MonthDays(_ref) {var _this = this;var month = _ref.month,selectedValue
57
59
  )] }
58
60
  ));
59
61
 
60
- }
62
+ });
61
63
 
62
- export function DayPicker(_ref2) {var _value2,_value3,_value4,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
64
+ export function DayPicker(_ref2) {var _value2,_value3,_value4,_value5,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
63
65
  if (!!value) value = dayjs(value);
64
66
  var _React$useState = React.useState(value),_React$useState2 = _slicedToArray(_React$useState, 2),localValue = _React$useState2[0],setLocalValue = _React$useState2[1];
65
67
  var _React$useState3 = React.useState(function () {return dayjs(value || undefined).startOf('month');}),_React$useState4 = _slicedToArray(_React$useState3, 2),currentMonth = _React$useState4[0],setCurrentMonth = _React$useState4[1];
@@ -70,19 +72,23 @@ export function DayPicker(_ref2) {var _value2,_value3,_value4,_this2 = this;var
70
72
  if ((_value = value) != null && _value.isValid != null && _value.isValid()) setCurrentMonth(value.startOf('month'));
71
73
  }, [(_value2 = value) == null ? void 0 : _value2.day == null ? void 0 : _value2.day(), (_value3 = value) == null ? void 0 : _value3.month == null ? void 0 : _value3.month(), (_value4 = value) == null ? void 0 : _value4.year == null ? void 0 : _value4.year()]);
72
74
 
73
- var handleChange = function handleChange(v) {
74
- setLocalValue(v);
75
- onChange == null ? void 0 : onChange(v);
76
- };
75
+ var handleChange = React.useCallback(
76
+ function (v) {
77
+ setLocalValue(v);
78
+ onChange == null ? void 0 : onChange(v);
79
+ },
80
+ [onChange]
81
+ );
77
82
 
78
83
  var monthValue = toMonthValue(currentMonth);
79
84
  var minMonth = min ? toMonthValue(dayjs(min).startOf('month')) : undefined;
80
85
  var maxMonth = max ? toMonthValue(dayjs(max).startOf('month')) : undefined;
86
+ var selectedKey = (_value5 = value) == null ? void 0 : _value5.valueOf == null ? void 0 : _value5.valueOf();
81
87
 
82
88
  var renderSlide = function renderSlide(v) {return (
83
89
  _jsx(MonthDays, {
84
- month: fromMonthValue(v),
85
- selectedValue: value,
90
+ monthValue: v,
91
+ selectedKey: selectedKey,
86
92
  onSelect: handleChange,
87
93
  min: min,
88
94
  max: max,
@@ -14,14 +14,15 @@ import { isDateDisabled } from "../../calendar/_helpers/dateDisabled";import { j
14
14
 
15
15
  var months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
16
16
 
17
- function MonthGrid(_ref) {var _this = this;var year = _ref.year,selectedValue = _ref.selectedValue,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
17
+ var MonthGrid = React.memo(function MonthGrid(_ref) {var _this = this;var year = _ref.year,selectedKey = _ref.selectedKey,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
18
18
  var yearDate = dayjs().year(year).startOf('year');
19
+ var selectedValue = selectedKey ? dayjs(selectedKey) : null;
19
20
 
20
21
  return (
21
22
  _jsx(Grid, { colSpan: 8, gap: "xs", children:
22
23
  months.map(function (month) {
23
24
  var dateVal = yearDate.month(month);
24
- var isActive = !!selectedValue && dateVal.isSame(selectedValue, 'week');
25
+ var isActive = !!selectedValue && dateVal.isSame(selectedValue, 'month');
25
26
  var disabled = isDateDisabled(dateVal, { min: min, max: max, onCheckDisabled: onCheckDisabled });
26
27
 
27
28
  return (
@@ -43,9 +44,9 @@ function MonthGrid(_ref) {var _this = this;var year = _ref.year,selectedValue =
43
44
  }) }
44
45
  ));
45
46
 
46
- }
47
+ });
47
48
 
48
- export function MonthPicker(_ref2) {var _value2,_value3,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
49
+ export function MonthPicker(_ref2) {var _value2,_value3,_value4,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
49
50
  var _React$useState = React.useState(value),_React$useState2 = _slicedToArray(_React$useState, 2),localValue = _React$useState2[0],setLocalValue = _React$useState2[1];
50
51
  var _React$useState3 = React.useState(function () {return dayjs(value || undefined).startOf('year');}),_React$useState4 = _slicedToArray(_React$useState3, 2),currentYear = _React$useState4[0],setCurrentYear = _React$useState4[1];
51
52
  value = value === undefined ? localValue : value;
@@ -55,18 +56,22 @@ export function MonthPicker(_ref2) {var _value2,_value3,_this2 = this;var value
55
56
  if ((_value = value) != null && _value.isValid != null && _value.isValid()) setCurrentYear(value.startOf('year'));
56
57
  }, [(_value2 = value) == null ? void 0 : _value2.month == null ? void 0 : _value2.month(), (_value3 = value) == null ? void 0 : _value3.year == null ? void 0 : _value3.year()]);
57
58
 
58
- var handleChange = function handleChange(v) {
59
- var newValue = v.startOf('month');
60
- setLocalValue(newValue);
61
- onChange == null ? void 0 : onChange(newValue);
62
- };
59
+ var handleChange = React.useCallback(
60
+ function (v) {
61
+ var newValue = v.startOf('month');
62
+ setLocalValue(newValue);
63
+ onChange == null ? void 0 : onChange(newValue);
64
+ },
65
+ [onChange]
66
+ );
63
67
 
64
68
  var yearValue = currentYear.year();
65
69
  var minYear = min ? dayjs(min).year() : undefined;
66
70
  var maxYear = max ? dayjs(max).year() : undefined;
71
+ var selectedKey = (_value4 = value) == null ? void 0 : _value4.valueOf == null ? void 0 : _value4.valueOf();
67
72
 
68
73
  var renderSlide = function renderSlide(v) {return (
69
- _jsx(MonthGrid, { year: v, selectedValue: value, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
74
+ _jsx(MonthGrid, { year: v, selectedKey: selectedKey, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
70
75
 
71
76
 
72
77
  return (
@@ -17,14 +17,15 @@ dayjs.extend(quarterOfYear);
17
17
 
18
18
  var quarters = [1, 2, 3, 4];
19
19
 
20
- function QuarterGrid(_ref) {var _this = this;var year = _ref.year,selectedValue = _ref.selectedValue,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
20
+ var QuarterGrid = React.memo(function QuarterGrid(_ref) {var _this = this;var year = _ref.year,selectedKey = _ref.selectedKey,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
21
21
  var yearDate = dayjs().year(year).startOf('year');
22
+ var selectedValue = selectedKey ? dayjs(selectedKey) : null;
22
23
 
23
24
  return (
24
25
  _jsx(Grid, { colSpan: 6, gap: "xs", children:
25
26
  quarters.map(function (quarter) {
26
27
  var dateVal = yearDate.quarter(quarter);
27
- var isActive = !!selectedValue && dateVal.isSame(selectedValue, 'week');
28
+ var isActive = !!selectedValue && dateVal.isSame(selectedValue, 'quarter');
28
29
  var disabled = isDateDisabled(dateVal, { min: min, max: max, onCheckDisabled: onCheckDisabled });
29
30
 
30
31
  return (
@@ -46,9 +47,9 @@ function QuarterGrid(_ref) {var _this = this;var year = _ref.year,selectedValue
46
47
  }) }
47
48
  ));
48
49
 
49
- }
50
+ });
50
51
 
51
- export function QuarterPicker(_ref2) {var _value2,_value3,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
52
+ export function QuarterPicker(_ref2) {var _value2,_value3,_value4,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
52
53
  var _React$useState = React.useState(value),_React$useState2 = _slicedToArray(_React$useState, 2),localValue = _React$useState2[0],setLocalValue = _React$useState2[1];
53
54
  var _React$useState3 = React.useState(function () {return dayjs(value || undefined).startOf('year');}),_React$useState4 = _slicedToArray(_React$useState3, 2),currentYear = _React$useState4[0],setCurrentYear = _React$useState4[1];
54
55
  value = value === undefined ? localValue : value;
@@ -58,18 +59,22 @@ export function QuarterPicker(_ref2) {var _value2,_value3,_this2 = this;var valu
58
59
  if ((_value = value) != null && _value.isValid != null && _value.isValid()) setCurrentYear(value.startOf('year'));
59
60
  }, [(_value2 = value) == null ? void 0 : _value2.quarter == null ? void 0 : _value2.quarter(), (_value3 = value) == null ? void 0 : _value3.year == null ? void 0 : _value3.year()]);
60
61
 
61
- var handleChange = function handleChange(v) {
62
- var newValue = v.startOf('quarter');
63
- setLocalValue(newValue);
64
- onChange == null ? void 0 : onChange(newValue);
65
- };
62
+ var handleChange = React.useCallback(
63
+ function (v) {
64
+ var newValue = v.startOf('quarter');
65
+ setLocalValue(newValue);
66
+ onChange == null ? void 0 : onChange(newValue);
67
+ },
68
+ [onChange]
69
+ );
66
70
 
67
71
  var yearValue = currentYear.year();
68
72
  var minYear = min ? dayjs(min).year() : undefined;
69
73
  var maxYear = max ? dayjs(max).year() : undefined;
74
+ var selectedKey = (_value4 = value) == null ? void 0 : _value4.valueOf == null ? void 0 : _value4.valueOf();
70
75
 
71
76
  var renderSlide = function renderSlide(v) {return (
72
- _jsx(QuarterGrid, { year: v, selectedValue: value, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
77
+ _jsx(QuarterGrid, { year: v, selectedKey: selectedKey, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
73
78
 
74
79
 
75
80
  return (
@@ -25,7 +25,9 @@ function fromMonthValue(v) {
25
25
  startOf('month');
26
26
  }
27
27
 
28
- function MonthWeeks(_ref) {var _this = this;var month = _ref.month,selectedValue = _ref.selectedValue,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
28
+ var MonthWeeks = React.memo(function MonthWeeks(_ref) {var _this = this;var monthValue = _ref.monthValue,selectedKey = _ref.selectedKey,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
29
+ var month = fromMonthValue(monthValue);
30
+ var selectedValue = selectedKey ? dayjs(selectedKey) : null;
29
31
  var _useCalendarDays = useCalendarDays(month),cells = _useCalendarDays.cells;
30
32
  var weeks = splitEvery(7, cells);
31
33
 
@@ -67,9 +69,9 @@ function MonthWeeks(_ref) {var _this = this;var month = _ref.month,selectedValue
67
69
  )] }
68
70
  ));
69
71
 
70
- }
72
+ });
71
73
 
72
- export function WeekPicker(_ref2) {var _value2,_value3,_value4,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
74
+ export function WeekPicker(_ref2) {var _value2,_value3,_value4,_value5,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
73
75
  var _React$useState = React.useState(value),_React$useState2 = _slicedToArray(_React$useState, 2),localValue = _React$useState2[0],setLocalValue = _React$useState2[1];
74
76
  var _React$useState3 = React.useState(function () {return dayjs(value || undefined).startOf('month');}),_React$useState4 = _slicedToArray(_React$useState3, 2),currentMonth = _React$useState4[0],setCurrentMonth = _React$useState4[1];
75
77
  value = value === undefined ? localValue : value;
@@ -79,18 +81,22 @@ export function WeekPicker(_ref2) {var _value2,_value3,_value4,_this2 = this;var
79
81
  if ((_value = value) != null && _value.isValid != null && _value.isValid()) setCurrentMonth(value.startOf('month'));
80
82
  }, [(_value2 = value) == null ? void 0 : _value2.day == null ? void 0 : _value2.day(), (_value3 = value) == null ? void 0 : _value3.month == null ? void 0 : _value3.month(), (_value4 = value) == null ? void 0 : _value4.year == null ? void 0 : _value4.year()]);
81
83
 
82
- var handleChange = function handleChange(v) {
83
- var newValue = v.startOf('week');
84
- setLocalValue(newValue);
85
- onChange == null ? void 0 : onChange(newValue);
86
- };
84
+ var handleChange = React.useCallback(
85
+ function (v) {
86
+ var newValue = v.startOf('week');
87
+ setLocalValue(newValue);
88
+ onChange == null ? void 0 : onChange(newValue);
89
+ },
90
+ [onChange]
91
+ );
87
92
 
88
93
  var monthValue = toMonthValue(currentMonth);
89
94
  var minMonth = min ? toMonthValue(dayjs(min).startOf('month')) : undefined;
90
95
  var maxMonth = max ? toMonthValue(dayjs(max).startOf('month')) : undefined;
96
+ var selectedKey = (_value5 = value) == null ? void 0 : _value5.valueOf == null ? void 0 : _value5.valueOf();
91
97
 
92
98
  var renderSlide = function renderSlide(v) {return (
93
- _jsx(MonthWeeks, { month: fromMonthValue(v), selectedValue: value, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
99
+ _jsx(MonthWeeks, { monthValue: v, selectedKey: selectedKey, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
94
100
 
95
101
 
96
102
  return (
@@ -21,15 +21,16 @@ function decadeFromIndex(i) {
21
21
  return dayjs().year(i * 10).startOf('year');
22
22
  }
23
23
 
24
- function DecadeGrid(_ref) {var _this = this;var decadeIndex = _ref.decadeIndex,selectedValue = _ref.selectedValue,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
24
+ var DecadeGrid = React.memo(function DecadeGrid(_ref) {var _this = this;var decadeIndex = _ref.decadeIndex,selectedKey = _ref.selectedKey,onSelect = _ref.onSelect,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
25
25
  var decadeStart = decadeFromIndex(decadeIndex);
26
+ var selectedValue = selectedKey ? dayjs(selectedKey) : null;
26
27
  var years = range(decadeStart.year(), decadeStart.year() + 10);
27
28
 
28
29
  return (
29
30
  _jsx(Grid, { colSpan: 12, gap: "xs", children:
30
31
  years.map(function (year) {
31
32
  var dateVal = decadeStart.year(year);
32
- var isActive = !!selectedValue && dateVal.isSame(selectedValue, 'week');
33
+ var isActive = !!selectedValue && dateVal.isSame(selectedValue, 'year');
33
34
  var disabled = isDateDisabled(dateVal, { min: min, max: max, onCheckDisabled: onCheckDisabled });
34
35
 
35
36
  return (
@@ -51,9 +52,9 @@ function DecadeGrid(_ref) {var _this = this;var decadeIndex = _ref.decadeIndex,s
51
52
  }) }
52
53
  ));
53
54
 
54
- }
55
+ });
55
56
 
56
- export function YearPicker(_ref2) {var _value2,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
57
+ export function YearPicker(_ref2) {var _value2,_value3,_this2 = this;var value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,allowClear = _ref2.allowClear,props = _objectWithoutProperties(_ref2, _excluded);
57
58
  var _React$useState = React.useState(value),_React$useState2 = _slicedToArray(_React$useState, 2),localValue = _React$useState2[0],setLocalValue = _React$useState2[1];
58
59
  var _React$useState3 = React.useState(function () {return getDecadeIndex(value);}),_React$useState4 = _slicedToArray(_React$useState3, 2),currentDecade = _React$useState4[0],setCurrentDecade = _React$useState4[1];
59
60
 
@@ -64,17 +65,21 @@ export function YearPicker(_ref2) {var _value2,_this2 = this;var value = _ref2.v
64
65
  if ((_value = value) != null && _value.isValid != null && _value.isValid()) setCurrentDecade(getDecadeIndex(value));
65
66
  }, [(_value2 = value) == null ? void 0 : _value2.year == null ? void 0 : _value2.year()]);
66
67
 
67
- var handleChange = function handleChange(v) {
68
- var newValue = v.startOf('year');
69
- setLocalValue(newValue);
70
- onChange == null ? void 0 : onChange(newValue);
71
- };
68
+ var handleChange = React.useCallback(
69
+ function (v) {
70
+ var newValue = v.startOf('year');
71
+ setLocalValue(newValue);
72
+ onChange == null ? void 0 : onChange(newValue);
73
+ },
74
+ [onChange]
75
+ );
72
76
 
73
77
  var minDecade = min ? getDecadeIndex(min) : undefined;
74
78
  var maxDecade = max ? getDecadeIndex(max) : undefined;
79
+ var selectedKey = (_value3 = value) == null ? void 0 : _value3.valueOf == null ? void 0 : _value3.valueOf();
75
80
 
76
81
  var renderSlide = function renderSlide(v) {return (
77
- _jsx(DecadeGrid, { decadeIndex: v, selectedValue: value, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
82
+ _jsx(DecadeGrid, { decadeIndex: v, selectedKey: selectedKey, onSelect: handleChange, min: min, max: max, onCheckDisabled: onCheckDisabled }));};
78
83
 
79
84
 
80
85
  return (
package/dist/index.js CHANGED
@@ -4,5 +4,6 @@ export * from "./theme";
4
4
  export * from "./responsive";
5
5
  export * from "./i18n";
6
6
  export * from "./NekoUI";
7
+ export * from "./abstractions";
7
8
 
8
9
  export var version = 41;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neko-os/ui",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "author": "Christian Storch <ccstorch@gmail.com>",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -0,0 +1 @@
1
+ export * from './Platform'
@@ -27,12 +27,20 @@ export function CarouselSlider() {
27
27
  const translateX = useSharedValue(0)
28
28
  const gestureStartX = useSharedValue(0)
29
29
  const prevItemsRef = React.useRef(items)
30
+ const gestureAnimatingRef = React.useRef(false)
31
+
32
+ const setGestureAnimating = React.useCallback((v) => {
33
+ gestureAnimatingRef.current = v
34
+ }, [])
30
35
 
31
36
  React.useEffect(() => {
32
37
  if (slideWidth > 0) {
33
38
  if (prevItemsRef.current !== items) {
34
39
  prevItemsRef.current = items
35
40
  translateX.value = -activeIndex * slideWidth
41
+ } else if (gestureAnimatingRef.current) {
42
+ // Gesture onEnd already animating — skip to avoid double animation
43
+ gestureAnimatingRef.current = false
36
44
  } else {
37
45
  translateX.value = withTiming(-activeIndex * slideWidth, { duration: 300 }, (finished) => {
38
46
  if (finished && afterChange) runOnJS(afterChange)(items?.[activeIndex]?.key, activeIndex)
@@ -87,7 +95,10 @@ export function CarouselSlider() {
87
95
  }
88
96
 
89
97
  const clamped = clampIndex(targetIndex, itemsCount, loop)
90
- translateX.value = withTiming(-clamped * slideWidth, { duration: 300 })
98
+ translateX.value = withTiming(-clamped * slideWidth, { duration: 300 }, (finished) => {
99
+ if (finished && afterChange) runOnJS(afterChange)(items?.[clamped]?.key, clamped)
100
+ })
101
+ runOnJS(setGestureAnimating)(true)
91
102
  runOnJS(goTo)(targetIndex)
92
103
  runOnJS(resumeAutoplay)()
93
104
  })
@@ -2,6 +2,7 @@ import { dissoc } from 'ramda'
2
2
  import React from 'react'
3
3
 
4
4
  import { Icon, IconLabel } from '../presentation'
5
+ import { KeyboardDismissButton } from '../keyboard'
5
6
  import { Link } from '../actions'
6
7
  import { LinkInput } from './LinkInput'
7
8
  import { Picker, getOptionLabel, searchOptions } from './Picker'
@@ -134,6 +135,8 @@ export function Select({
134
135
  maxHeight={popoverMaxHeight}
135
136
  {...popoverProps}
136
137
  renderContent={({ onClose }) => (
138
+ <>
139
+ {useBottomDrawer && useSearch && <KeyboardDismissButton />}
137
140
  <Picker
138
141
  row={false}
139
142
  options={searchOptions(options, search, { labelKey })}
@@ -152,21 +155,21 @@ export function Select({
152
155
  }}
153
156
  {...pickerProps}
154
157
  renderHeader={
155
- useBottomDrawer && useSearch
156
- ? () => (
157
- <>
158
- <View padding="md" paddingB="xs">
159
- <TextInput
160
- prefixIcon="search-line"
161
- prefixIconColor="text4"
162
- value={search}
163
- onChange={handleChangeSearch}
164
- />
165
- </View>
166
- {renderHeader?.()}
167
- </>
168
- )
169
- : renderHeader
158
+ useBottomDrawer && useSearch ? (
159
+ <>
160
+ <View padding="md" paddingB="xs">
161
+ <TextInput
162
+ prefixIcon="search-line"
163
+ prefixIconColor="text4"
164
+ value={search}
165
+ onChange={handleChangeSearch}
166
+ />
167
+ </View>
168
+ {renderHeader?.()}
169
+ </>
170
+ ) : (
171
+ renderHeader
172
+ )
170
173
  }
171
174
  renderOption={({ option, selected, onChange }) => (
172
175
  <Link
@@ -187,6 +190,7 @@ export function Select({
187
190
  </Link>
188
191
  )}
189
192
  />
193
+ </>
190
194
  )}
191
195
  >
192
196
  <Input
@@ -24,7 +24,9 @@ function fromMonthValue(v) {
24
24
  .startOf('month')
25
25
  }
26
26
 
27
- function MonthDays({ month, selectedValue, onSelect, min, max, onCheckDisabled }) {
27
+ const MonthDays = React.memo(function MonthDays({ monthValue, selectedKey, onSelect, min, max, onCheckDisabled }) {
28
+ const month = fromMonthValue(monthValue)
29
+ const selectedValue = selectedKey ? dayjs(selectedKey) : null
28
30
  const { cells } = useCalendarDays(month)
29
31
 
30
32
  return (
@@ -57,7 +59,7 @@ function MonthDays({ month, selectedValue, onSelect, min, max, onCheckDisabled }
57
59
  </Grid>
58
60
  </View>
59
61
  )
60
- }
62
+ })
61
63
 
62
64
  export function DayPicker({ value, onChange, min, max, onCheckDisabled, allowClear, ...props }) {
63
65
  if (!!value) value = dayjs(value)
@@ -70,19 +72,23 @@ export function DayPicker({ value, onChange, min, max, onCheckDisabled, allowCle
70
72
  if (value?.isValid?.()) setCurrentMonth(value.startOf('month'))
71
73
  }, [value?.day?.(), value?.month?.(), value?.year?.()])
72
74
 
73
- const handleChange = (v) => {
74
- setLocalValue(v)
75
- onChange?.(v)
76
- }
75
+ const handleChange = React.useCallback(
76
+ (v) => {
77
+ setLocalValue(v)
78
+ onChange?.(v)
79
+ },
80
+ [onChange]
81
+ )
77
82
 
78
83
  const monthValue = toMonthValue(currentMonth)
79
84
  const minMonth = min ? toMonthValue(dayjs(min).startOf('month')) : undefined
80
85
  const maxMonth = max ? toMonthValue(dayjs(max).startOf('month')) : undefined
86
+ const selectedKey = value?.valueOf?.()
81
87
 
82
88
  const renderSlide = (v) => (
83
89
  <MonthDays
84
- month={fromMonthValue(v)}
85
- selectedValue={value}
90
+ monthValue={v}
91
+ selectedKey={selectedKey}
86
92
  onSelect={handleChange}
87
93
  min={min}
88
94
  max={max}
@@ -14,14 +14,15 @@ import { isDateDisabled } from '../../calendar/_helpers/dateDisabled'
14
14
 
15
15
  const months = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
16
16
 
17
- function MonthGrid({ year, selectedValue, onSelect, min, max, onCheckDisabled }) {
17
+ const MonthGrid = React.memo(function MonthGrid({ year, selectedKey, onSelect, min, max, onCheckDisabled }) {
18
18
  const yearDate = dayjs().year(year).startOf('year')
19
+ const selectedValue = selectedKey ? dayjs(selectedKey) : null
19
20
 
20
21
  return (
21
22
  <Grid colSpan={8} gap="xs">
22
23
  {months.map((month) => {
23
24
  const dateVal = yearDate.month(month)
24
- const isActive = !!selectedValue && dateVal.isSame(selectedValue, 'week')
25
+ const isActive = !!selectedValue && dateVal.isSame(selectedValue, 'month')
25
26
  const disabled = isDateDisabled(dateVal, { min, max, onCheckDisabled })
26
27
 
27
28
  return (
@@ -43,7 +44,7 @@ function MonthGrid({ year, selectedValue, onSelect, min, max, onCheckDisabled })
43
44
  })}
44
45
  </Grid>
45
46
  )
46
- }
47
+ })
47
48
 
48
49
  export function MonthPicker({ value, onChange, min, max, onCheckDisabled, allowClear, ...props }) {
49
50
  const [localValue, setLocalValue] = React.useState(value)
@@ -55,18 +56,22 @@ export function MonthPicker({ value, onChange, min, max, onCheckDisabled, allowC
55
56
  if (value?.isValid?.()) setCurrentYear(value.startOf('year'))
56
57
  }, [value?.month?.(), value?.year?.()])
57
58
 
58
- const handleChange = (v) => {
59
- const newValue = v.startOf('month')
60
- setLocalValue(newValue)
61
- onChange?.(newValue)
62
- }
59
+ const handleChange = React.useCallback(
60
+ (v) => {
61
+ const newValue = v.startOf('month')
62
+ setLocalValue(newValue)
63
+ onChange?.(newValue)
64
+ },
65
+ [onChange]
66
+ )
63
67
 
64
68
  const yearValue = currentYear.year()
65
69
  const minYear = min ? dayjs(min).year() : undefined
66
70
  const maxYear = max ? dayjs(max).year() : undefined
71
+ const selectedKey = value?.valueOf?.()
67
72
 
68
73
  const renderSlide = (v) => (
69
- <MonthGrid year={v} selectedValue={value} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
74
+ <MonthGrid year={v} selectedKey={selectedKey} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
70
75
  )
71
76
 
72
77
  return (
@@ -17,14 +17,15 @@ dayjs.extend(quarterOfYear)
17
17
 
18
18
  const quarters = [1, 2, 3, 4]
19
19
 
20
- function QuarterGrid({ year, selectedValue, onSelect, min, max, onCheckDisabled }) {
20
+ const QuarterGrid = React.memo(function QuarterGrid({ year, selectedKey, onSelect, min, max, onCheckDisabled }) {
21
21
  const yearDate = dayjs().year(year).startOf('year')
22
+ const selectedValue = selectedKey ? dayjs(selectedKey) : null
22
23
 
23
24
  return (
24
25
  <Grid colSpan={6} gap="xs">
25
26
  {quarters.map((quarter) => {
26
27
  const dateVal = yearDate.quarter(quarter)
27
- const isActive = !!selectedValue && dateVal.isSame(selectedValue, 'week')
28
+ const isActive = !!selectedValue && dateVal.isSame(selectedValue, 'quarter')
28
29
  const disabled = isDateDisabled(dateVal, { min, max, onCheckDisabled })
29
30
 
30
31
  return (
@@ -46,7 +47,7 @@ function QuarterGrid({ year, selectedValue, onSelect, min, max, onCheckDisabled
46
47
  })}
47
48
  </Grid>
48
49
  )
49
- }
50
+ })
50
51
 
51
52
  export function QuarterPicker({ value, onChange, min, max, onCheckDisabled, allowClear, ...props }) {
52
53
  const [localValue, setLocalValue] = React.useState(value)
@@ -58,18 +59,22 @@ export function QuarterPicker({ value, onChange, min, max, onCheckDisabled, allo
58
59
  if (value?.isValid?.()) setCurrentYear(value.startOf('year'))
59
60
  }, [value?.quarter?.(), value?.year?.()])
60
61
 
61
- const handleChange = (v) => {
62
- const newValue = v.startOf('quarter')
63
- setLocalValue(newValue)
64
- onChange?.(newValue)
65
- }
62
+ const handleChange = React.useCallback(
63
+ (v) => {
64
+ const newValue = v.startOf('quarter')
65
+ setLocalValue(newValue)
66
+ onChange?.(newValue)
67
+ },
68
+ [onChange]
69
+ )
66
70
 
67
71
  const yearValue = currentYear.year()
68
72
  const minYear = min ? dayjs(min).year() : undefined
69
73
  const maxYear = max ? dayjs(max).year() : undefined
74
+ const selectedKey = value?.valueOf?.()
70
75
 
71
76
  const renderSlide = (v) => (
72
- <QuarterGrid year={v} selectedValue={value} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
77
+ <QuarterGrid year={v} selectedKey={selectedKey} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
73
78
  )
74
79
 
75
80
  return (
@@ -25,7 +25,9 @@ function fromMonthValue(v) {
25
25
  .startOf('month')
26
26
  }
27
27
 
28
- function MonthWeeks({ month, selectedValue, onSelect, min, max, onCheckDisabled }) {
28
+ const MonthWeeks = React.memo(function MonthWeeks({ monthValue, selectedKey, onSelect, min, max, onCheckDisabled }) {
29
+ const month = fromMonthValue(monthValue)
30
+ const selectedValue = selectedKey ? dayjs(selectedKey) : null
29
31
  const { cells } = useCalendarDays(month)
30
32
  const weeks = splitEvery(7, cells)
31
33
 
@@ -67,7 +69,7 @@ function MonthWeeks({ month, selectedValue, onSelect, min, max, onCheckDisabled
67
69
  </View>
68
70
  </View>
69
71
  )
70
- }
72
+ })
71
73
 
72
74
  export function WeekPicker({ value, onChange, min, max, onCheckDisabled, allowClear, ...props }) {
73
75
  const [localValue, setLocalValue] = React.useState(value)
@@ -79,18 +81,22 @@ export function WeekPicker({ value, onChange, min, max, onCheckDisabled, allowCl
79
81
  if (value?.isValid?.()) setCurrentMonth(value.startOf('month'))
80
82
  }, [value?.day?.(), value?.month?.(), value?.year?.()])
81
83
 
82
- const handleChange = (v) => {
83
- const newValue = v.startOf('week')
84
- setLocalValue(newValue)
85
- onChange?.(newValue)
86
- }
84
+ const handleChange = React.useCallback(
85
+ (v) => {
86
+ const newValue = v.startOf('week')
87
+ setLocalValue(newValue)
88
+ onChange?.(newValue)
89
+ },
90
+ [onChange]
91
+ )
87
92
 
88
93
  const monthValue = toMonthValue(currentMonth)
89
94
  const minMonth = min ? toMonthValue(dayjs(min).startOf('month')) : undefined
90
95
  const maxMonth = max ? toMonthValue(dayjs(max).startOf('month')) : undefined
96
+ const selectedKey = value?.valueOf?.()
91
97
 
92
98
  const renderSlide = (v) => (
93
- <MonthWeeks month={fromMonthValue(v)} selectedValue={value} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
99
+ <MonthWeeks monthValue={v} selectedKey={selectedKey} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
94
100
  )
95
101
 
96
102
  return (
@@ -21,15 +21,16 @@ function decadeFromIndex(i) {
21
21
  return dayjs().year(i * 10).startOf('year')
22
22
  }
23
23
 
24
- function DecadeGrid({ decadeIndex, selectedValue, onSelect, min, max, onCheckDisabled }) {
24
+ const DecadeGrid = React.memo(function DecadeGrid({ decadeIndex, selectedKey, onSelect, min, max, onCheckDisabled }) {
25
25
  const decadeStart = decadeFromIndex(decadeIndex)
26
+ const selectedValue = selectedKey ? dayjs(selectedKey) : null
26
27
  const years = range(decadeStart.year(), decadeStart.year() + 10)
27
28
 
28
29
  return (
29
30
  <Grid colSpan={12} gap="xs">
30
31
  {years.map((year) => {
31
32
  const dateVal = decadeStart.year(year)
32
- const isActive = !!selectedValue && dateVal.isSame(selectedValue, 'week')
33
+ const isActive = !!selectedValue && dateVal.isSame(selectedValue, 'year')
33
34
  const disabled = isDateDisabled(dateVal, { min, max, onCheckDisabled })
34
35
 
35
36
  return (
@@ -51,7 +52,7 @@ function DecadeGrid({ decadeIndex, selectedValue, onSelect, min, max, onCheckDis
51
52
  })}
52
53
  </Grid>
53
54
  )
54
- }
55
+ })
55
56
 
56
57
  export function YearPicker({ value, onChange, min, max, onCheckDisabled, allowClear, ...props }) {
57
58
  const [localValue, setLocalValue] = React.useState(value)
@@ -64,17 +65,21 @@ export function YearPicker({ value, onChange, min, max, onCheckDisabled, allowCl
64
65
  if (value?.isValid?.()) setCurrentDecade(getDecadeIndex(value))
65
66
  }, [value?.year?.()])
66
67
 
67
- const handleChange = (v) => {
68
- const newValue = v.startOf('year')
69
- setLocalValue(newValue)
70
- onChange?.(newValue)
71
- }
68
+ const handleChange = React.useCallback(
69
+ (v) => {
70
+ const newValue = v.startOf('year')
71
+ setLocalValue(newValue)
72
+ onChange?.(newValue)
73
+ },
74
+ [onChange]
75
+ )
72
76
 
73
77
  const minDecade = min ? getDecadeIndex(min) : undefined
74
78
  const maxDecade = max ? getDecadeIndex(max) : undefined
79
+ const selectedKey = value?.valueOf?.()
75
80
 
76
81
  const renderSlide = (v) => (
77
- <DecadeGrid decadeIndex={v} selectedValue={value} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
82
+ <DecadeGrid decadeIndex={v} selectedKey={selectedKey} onSelect={handleChange} min={min} max={max} onCheckDisabled={onCheckDisabled} />
78
83
  )
79
84
 
80
85
  return (
package/src/index.js CHANGED
@@ -4,5 +4,6 @@ export * from './theme'
4
4
  export * from './responsive'
5
5
  export * from './i18n'
6
6
  export * from './NekoUI'
7
+ export * from './abstractions'
7
8
 
8
9
  export const version = 41