@neko-os/ui 0.5.1 → 0.5.3

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.
package/README.md CHANGED
@@ -1,3 +1,5 @@
1
1
  # Neko UI
2
2
 
3
3
  Universal React Native UI library (works on react-native, react-native-web and react).
4
+
5
+ https://nekoui.surge.sh/guides/install
package/dist/NekoUI.js CHANGED
@@ -1,4 +1,5 @@
1
- var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/NekoUI.js";var _excluded = ["children", "i18n"];function _objectWithoutProperties(e, t) {if (null == e) return {};var o,r,i = _objectWithoutPropertiesLoose(e, t);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(e);for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);}return i;}function _objectWithoutPropertiesLoose(r, e) {if (null == r) return {};var t = {};for (var n in r) if ({}.hasOwnProperty.call(r, n)) {if (-1 !== e.indexOf(n)) continue;t[n] = r[n];}return t;}import { DynamicStyleTag } from "./DynamicStyleTag";
1
+ var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/NekoUI.js";var _excluded = ["children", "i18n"];function _objectWithoutProperties(e, t) {if (null == e) return {};var o,r,i = _objectWithoutPropertiesLoose(e, t);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(e);for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);}return i;}function _objectWithoutPropertiesLoose(r, e) {if (null == r) return {};var t = {};for (var n in r) if ({}.hasOwnProperty.call(r, n)) {if (-1 !== e.indexOf(n)) continue;t[n] = r[n];}return t;}import { initFirstDayOfWeek } from "./helpers/weekStartSetup";
2
+ import { DynamicStyleTag } from "./DynamicStyleTag";
2
3
  import { I18nProvider } from "./i18n";
3
4
  import { ModalsHandler } from "./components/modals/modal/handler/ModalsHandler";
4
5
  import { NotificationsHandler } from "./components/feedback/notifications/NotificationsHandler";
@@ -9,6 +10,8 @@ import { ThemeHandler } from "./theme/ThemeHandler";
9
10
  import { ThemePickerDrawer } from "./components/theme";
10
11
  import { useThemeHandler } from "./theme";import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
12
 
13
+ initFirstDayOfWeek();
14
+
12
15
  export function NekoUI(_ref) {var children = _ref.children,i18n = _ref.i18n,props = _objectWithoutProperties(_ref, _excluded);
13
16
  return (
14
17
  _jsxs(ThemeHandler, Object.assign({}, props, { children: [
@@ -1,4 +1,4 @@
1
- var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/actions/Dropdown.js";var _excluded = ["items"],_excluded2 = ["onChange", "label", "trigger", "icon", "strong", "color", "popoverProps", "iconLabelProps", "children", "placement", "gap", "useBottomDrawer"];function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}function _objectWithoutProperties(e, t) {if (null == e) return {};var o,r,i = _objectWithoutPropertiesLoose(e, t);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(e);for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);}return i;}function _objectWithoutPropertiesLoose(r, e) {if (null == r) return {};var t = {};for (var n in r) if ({}.hasOwnProperty.call(r, n)) {if (-1 !== e.indexOf(n)) continue;t[n] = r[n];}return t;}import { pipe } from 'ramda';
1
+ var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/actions/Dropdown.js";var _excluded = ["items"],_excluded2 = ["onChange", "label", "trigger", "icon", "strong", "color", "popoverProps", "iconLabelProps", "children", "placement", "gap", "useBottomDrawer", "snapPoints"];function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}function _objectWithoutProperties(e, t) {if (null == e) return {};var o,r,i = _objectWithoutPropertiesLoose(e, t);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(e);for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);}return i;}function _objectWithoutPropertiesLoose(r, e) {if (null == r) return {};var t = {};for (var n in r) if ({}.hasOwnProperty.call(r, n)) {if (-1 !== e.indexOf(n)) continue;t[n] = r[n];}return t;}import { pipe } from 'ramda';
2
2
 
3
3
  import { DrawerScrollView } from "../modals";
4
4
  import { IconLabel } from "../presentation/IconLabel";
@@ -38,7 +38,8 @@ export function Dropdown(_ref) {var _this = this;var items = _ref.items,rootProp
38
38
 
39
39
 
40
40
 
41
- formattedProps.onChange,label = formattedProps.label,_formattedProps$trigg = formattedProps.trigger,trigger = _formattedProps$trigg === void 0 ? 'click' : _formattedProps$trigg,icon = formattedProps.icon,strong = formattedProps.strong,color = formattedProps.color,popoverProps = formattedProps.popoverProps,iconLabelProps = formattedProps.iconLabelProps,children = formattedProps.children,placement = formattedProps.placement,gap = formattedProps.gap,useBottomDrawer = formattedProps.useBottomDrawer,props = _objectWithoutProperties(formattedProps, _excluded2);
41
+
42
+ formattedProps.onChange,label = formattedProps.label,_formattedProps$trigg = formattedProps.trigger,trigger = _formattedProps$trigg === void 0 ? 'click' : _formattedProps$trigg,icon = formattedProps.icon,strong = formattedProps.strong,color = formattedProps.color,popoverProps = formattedProps.popoverProps,iconLabelProps = formattedProps.iconLabelProps,children = formattedProps.children,placement = formattedProps.placement,gap = formattedProps.gap,useBottomDrawer = formattedProps.useBottomDrawer,snapPoints = formattedProps.snapPoints,props = _objectWithoutProperties(formattedProps, _excluded2);
42
43
 
43
44
  useBottomDrawer = useResponsiveValue(useBottomDrawer || { native: true, sm: true, md: true });
44
45
 
@@ -51,7 +52,8 @@ export function Dropdown(_ref) {var _this = this;var items = _ref.items,rootProp
51
52
  padding: 0,
52
53
 
53
54
  contentProps: { padding: 0 },
54
- useBottomDrawer: useBottomDrawer },
55
+ useBottomDrawer: useBottomDrawer,
56
+ snapPoints: snapPoints },
55
57
  popoverProps, {
56
58
  renderContent: function renderContent(_ref2) {var onClose = _ref2.onClose;
57
59
  var handleChange = function handleChange() {
@@ -0,0 +1,176 @@
1
+ var _excluded = ["type", "value", "onChange", "min", "max", "onCheckDisabled"];var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/calendar/PeriodNavBar.js";function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}function _objectWithoutProperties(e, t) {if (null == e) return {};var o,r,i = _objectWithoutPropertiesLoose(e, t);if (Object.getOwnPropertySymbols) {var n = Object.getOwnPropertySymbols(e);for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);}return i;}function _objectWithoutPropertiesLoose(r, e) {if (null == r) return {};var t = {};for (var n in r) if ({}.hasOwnProperty.call(r, n)) {if (-1 !== e.indexOf(n)) continue;t[n] = r[n];}return t;}import React from 'react';
2
+ import dayjs from 'dayjs';
3
+ import quarterOfYear from 'dayjs/esm/plugin/quarterOfYear';
4
+
5
+ import { InfiniteCarousel } from "../carousel/InfiniteCarousel";
6
+ import { Link } from "../actions/Link";
7
+ import { Text } from "../text/Text";
8
+ import { View } from "../structure/View";
9
+ import { isDateDisabled } from "./_helpers/dateDisabled";import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
10
+
11
+ dayjs.extend(quarterOfYear);
12
+
13
+ function getWeekEpoch() {
14
+ return dayjs('2000-01-01').startOf('week');
15
+ }
16
+
17
+ var TYPES = {
18
+ day: {
19
+ count: 7,
20
+ unit: 'day',
21
+ toPageValue: function toPageValue(date) {
22
+ return date.startOf('week').diff(getWeekEpoch(), 'week');
23
+ },
24
+ getItems: function getItems(pageValue) {
25
+ var weekStart = getWeekEpoch().add(pageValue, 'week');
26
+ return Array.from({ length: 7 }, function (_, i) {
27
+ var d = weekStart.add(i, 'day');
28
+ return { key: d.valueOf(), date: d, label: d.format('ddd'), sublabel: String(d.date()) };
29
+ });
30
+ }
31
+ },
32
+ week: {
33
+ count: 7,
34
+ unit: 'week',
35
+ toPageValue: function toPageValue(date) {
36
+ var weekIndex = date.startOf('week').diff(getWeekEpoch(), 'week');
37
+ return Math.floor(weekIndex / 7);
38
+ },
39
+ getItems: function getItems(pageValue) {
40
+ return Array.from({ length: 7 }, function (_, i) {
41
+ var weekIndex = pageValue * 7 + i;
42
+ var d = getWeekEpoch().add(weekIndex, 'week');
43
+ var end = d.add(6, 'day');
44
+ return { key: d.valueOf(), date: d, label: `${d.date()}-${end.date()}`, sublabel: d.format('MMM') };
45
+ });
46
+ }
47
+ },
48
+ month: {
49
+ count: 7,
50
+ unit: 'month',
51
+ toPageValue: function toPageValue(date) {
52
+ var absMonth = date.year() * 12 + date.month();
53
+ return Math.floor(absMonth / 7);
54
+ },
55
+ getItems: function getItems(pageValue) {
56
+ return Array.from({ length: 7 }, function (_, i) {
57
+ var absMonth = pageValue * 7 + i;
58
+ var year = Math.floor(absMonth / 12);
59
+ var month = absMonth % 12;
60
+ var d = dayjs().year(year).month(month).startOf('month');
61
+ return { key: d.valueOf(), date: d, label: d.format('MMM'), sublabel: d.format("'YY") };
62
+ });
63
+ }
64
+ },
65
+ quarter: {
66
+ count: 4,
67
+ unit: 'quarter',
68
+ toPageValue: function toPageValue(date) {
69
+ return date.year();
70
+ },
71
+ getItems: function getItems(pageValue) {
72
+ return Array.from({ length: 4 }, function (_, i) {
73
+ var d = dayjs().year(pageValue).month(i * 3).startOf('month');
74
+ return { key: d.valueOf(), date: d, label: `Q${i + 1}`, sublabel: String(pageValue) };
75
+ });
76
+ }
77
+ },
78
+ year: {
79
+ count: 7,
80
+ unit: 'year',
81
+ toPageValue: function toPageValue(date) {
82
+ return Math.floor(date.year() / 7);
83
+ },
84
+ getItems: function getItems(pageValue) {
85
+ return Array.from({ length: 7 }, function (_, i) {
86
+ var year = pageValue * 7 + i;
87
+ var d = dayjs().year(year).startOf('year');
88
+ return { key: d.valueOf(), date: d, label: String(year), sublabel: null };
89
+ });
90
+ }
91
+ }
92
+ };
93
+
94
+ var PeriodSlide = React.memo(function PeriodSlide(_ref) {var _this = this;var items = _ref.items,value = _ref.value,unit = _ref.unit,onChange = _ref.onChange,min = _ref.min,max = _ref.max,onCheckDisabled = _ref.onCheckDisabled;
95
+ return (
96
+ _jsx(View, { row: true, center: true, gap: "xs", children:
97
+ items.map(function (item) {
98
+ var isActive = !!value && dayjs(value).isSame(item.date, unit);
99
+ var disabled = isDateDisabled(item.date, { min: min, max: max, onCheckDisabled: onCheckDisabled });
100
+
101
+ return (
102
+ _jsxs(Link, {
103
+
104
+ flex: true,
105
+ center: true,
106
+ br: "md",
107
+ paddingV: "xs",
108
+ onPress: function onPress() {return onChange(item.date);},
109
+ bg: isActive && 'primary',
110
+ disabled: disabled, children: [
111
+
112
+ _jsx(Text, { sm: true, center: true, strong: isActive, text2: !isActive, children:
113
+ item.label }
114
+ ),
115
+ item.sublabel &&
116
+ _jsx(Text, { xxs: true, center: true, text4: !isActive, strong: isActive, children:
117
+ item.sublabel }
118
+ )] }, item.key
119
+
120
+ ));
121
+
122
+ }) }
123
+ ));
124
+
125
+ });
126
+
127
+ export function PeriodNavBar(_ref2) {var _this2 = this;var _ref2$type = _ref2.type,type = _ref2$type === void 0 ? 'day' : _ref2$type,value = _ref2.value,onChange = _ref2.onChange,min = _ref2.min,max = _ref2.max,onCheckDisabled = _ref2.onCheckDisabled,props = _objectWithoutProperties(_ref2, _excluded);
128
+ var config = TYPES[type];
129
+ var _React$useState = React.useState(value),_React$useState2 = _slicedToArray(_React$useState, 2),localValue = _React$useState2[0],setLocalValue = _React$useState2[1];
130
+ var resolvedValue = value === undefined ? localValue : value;
131
+
132
+ var _React$useState3 = React.useState(function () {
133
+ var date = resolvedValue ? dayjs(resolvedValue) : dayjs();
134
+ return config.toPageValue(date);
135
+ }),_React$useState4 = _slicedToArray(_React$useState3, 2),currentPage = _React$useState4[0],setCurrentPage = _React$useState4[1];
136
+
137
+ React.useEffect(function () {
138
+ var date = resolvedValue ? dayjs(resolvedValue) : dayjs();
139
+ setCurrentPage(TYPES[type].toPageValue(date));
140
+ }, [resolvedValue, type]);
141
+
142
+ var handleSelect = React.useCallback(
143
+ function (date) {
144
+ setLocalValue(date);
145
+ onChange == null ? void 0 : onChange(date);
146
+ },
147
+ [onChange]
148
+ );
149
+
150
+ var minPage = min ? config.toPageValue(dayjs(min)) : undefined;
151
+ var maxPage = max ? config.toPageValue(dayjs(max)) : undefined;
152
+
153
+ var renderSlide = function renderSlide(pageValue) {return (
154
+ _jsx(PeriodSlide, {
155
+ items: config.getItems(pageValue),
156
+ value: resolvedValue,
157
+ unit: config.unit,
158
+ onChange: handleSelect,
159
+ min: min,
160
+ max: max,
161
+ onCheckDisabled: onCheckDisabled }
162
+ ));};
163
+
164
+
165
+ return (
166
+ _jsx(View, Object.assign({ className: "neko-period-nav-bar" }, props, { children:
167
+ _jsx(InfiniteCarousel, {
168
+ value: currentPage,
169
+ onChange: setCurrentPage,
170
+ renderSlide: renderSlide,
171
+ min: minPage,
172
+ max: maxPage }
173
+ ) })
174
+ ));
175
+
176
+ }
@@ -1,12 +1,16 @@
1
- var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/calendar/WeekDaysBar.js";import { Text } from "../text/Text";
2
- import { View } from "../structure/View";import { jsx as _jsx } from "react/jsx-runtime";
1
+ var _jsxFileName = "/Users/christianstorch/Apps/nekoapps/libs/neko-ui/src/components/calendar/WeekDaysBar.js";function _toConsumableArray(r) {return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();}function _nonIterableSpread() {throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _iterableToArray(r) {if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);}function _arrayWithoutHoles(r) {if (Array.isArray(r)) return _arrayLikeToArray(r);}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}import { Text } from "../text/Text";
2
+ import { View } from "../structure/View";
3
+ import { getFirstDayOfWeek } from "../../helpers/weekStart";import { jsx as _jsx } from "react/jsx-runtime";
3
4
 
4
- var weekdayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
5
+ var ALL_DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
5
6
 
6
7
  export function WeekDaysBar() {var _this = this;
8
+ var firstDay = getFirstDayOfWeek();
9
+ var labels = [].concat(_toConsumableArray(ALL_DAYS.slice(firstDay)), _toConsumableArray(ALL_DAYS.slice(0, firstDay)));
10
+
7
11
  return (
8
12
  _jsx(View, { className: "neko-week-days-bar", row: true, center: true, gap: "sm", children:
9
- weekdayLabels.map(function (w) {return (
13
+ labels.map(function (w) {return (
10
14
  _jsx(View, { flex: true, height: 30, center: true, children:
11
15
  _jsx(Text, { center: true, sm: true, text4: true, children:
12
16
  w }
@@ -1,13 +1,17 @@
1
1
  import dayjs from 'dayjs';
2
2
  import React from 'react';
3
3
 
4
+ import { getFirstDayOfWeek } from "../../../helpers/weekStart";
5
+
4
6
  export function useCalendarDays(currentMonth) {
5
7
  return React.useMemo(function () {var _currentMonth;
6
8
  if (!((_currentMonth = currentMonth) != null && _currentMonth.isValid != null && _currentMonth.isValid())) currentMonth = dayjs();
7
9
  var startWeekday = currentMonth.startOf('month').day();
10
+ var firstDay = getFirstDayOfWeek();
11
+ var offset = (startWeekday - firstDay + 7) % 7;
8
12
  var daysInMonth = currentMonth.daysInMonth();
9
13
 
10
- var blanks = Array.from({ length: startWeekday }, function () {return null;});
14
+ var blanks = Array.from({ length: offset }, function () {return null;});
11
15
  var days = Array.from({ length: daysInMonth }, function (_, i) {return i + 1;});
12
16
  var cells = [].concat(blanks, days);
13
17
 
@@ -0,0 +1 @@
1
+ export * from "./PeriodNavBar";
@@ -33,7 +33,7 @@ function formatValue(value, type) {
33
33
  case 'month':
34
34
  return [date.startOf('month'), date.endOf('month')];
35
35
  case 'week':
36
- return [date.startOf('isoWeek'), date.endOf('isoWeek')];
36
+ return [date.startOf('week'), date.endOf('week')];
37
37
  default:
38
38
  return [date.startOf('day'), date.endOf('day')];
39
39
  }
@@ -62,6 +62,7 @@ export function FormItem(_ref)
62
62
 
63
63
  var handleBlur = function handleBlur(e, originalOnBlur) {
64
64
  if (originalOnBlur) originalOnBlur(e);
65
+ form.markTouched(listPath);
65
66
 
66
67
  if (shouldValidateOn('onBlur', rules, validateTrigger)) {
67
68
  form.validateField(listPath, 'onBlur');
@@ -1,4 +1,4 @@
1
- function asyncGeneratorStep(n, t, e, r, o, a, c) {try {var i = n[a](c),u = i.value;} catch (n) {return void e(n);}i.done ? t(u) : Promise.resolve(u).then(r, o);}function _asyncToGenerator(n) {return function () {var t = this,e = arguments;return new Promise(function (r, o) {var a = n.apply(t, e);function _next(n) {asyncGeneratorStep(a, r, o, _next, _throw, "next", n);}function _throw(n) {asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);}_next(void 0);});};}function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}import { assocPath, path } from 'ramda';
1
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {try {var i = n[a](c),u = i.value;} catch (n) {return void e(n);}i.done ? t(u) : Promise.resolve(u).then(r, o);}function _asyncToGenerator(n) {return function () {var t = this,e = arguments;return new Promise(function (r, o) {var a = n.apply(t, e);function _next(n) {asyncGeneratorStep(a, r, o, _next, _throw, "next", n);}function _throw(n) {asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);}_next(void 0);});};}function _slicedToArray(r, e) {return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();}function _nonIterableRest() {throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _iterableToArrayLimit(r, l) {var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];if (null != t) {var e,n,i,u,a = [],f = !0,o = !1;try {if (i = (t = t.call(r)).next, 0 === l) {if (Object(t) !== t) return;f = !1;} else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);} catch (r) {o = !0, n = r;} finally {try {if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;} finally {if (o) throw n;}}return a;}}function _arrayWithHoles(r) {if (Array.isArray(r)) return r;}function _toConsumableArray(r) {return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();}function _nonIterableSpread() {throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(r, a) {if (r) {if ("string" == typeof r) return _arrayLikeToArray(r, a);var t = {}.toString.call(r).slice(8, -1);return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;}}function _iterableToArray(r) {if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);}function _arrayWithoutHoles(r) {if (Array.isArray(r)) return _arrayLikeToArray(r);}function _arrayLikeToArray(r, a) {(null == a || a > r.length) && (a = r.length);for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];return n;}import { assocPath, path } from 'ramda';
2
2
  import React from 'react';
3
3
  import { validateRules, validateAllFields, normalizeRules } from "./validation";
4
4
 
@@ -6,6 +6,8 @@ export function useNewForm() {var _ref = arguments.length > 0 && arguments[0] !=
6
6
  var valuesRef = React.useRef(Object.assign({}, initialValues));
7
7
  var initialValuesRef = React.useRef(Object.assign({}, initialValues));
8
8
  var errorsRef = React.useRef({});
9
+ var touchedRef = React.useRef(new Set());
10
+ var dirtyRef = React.useRef(new Set());
9
11
  var listenersRef = React.useRef({});
10
12
  var errorListenersRef = React.useRef({});
11
13
  var rulesRegistryRef = React.useRef(new Map());
@@ -45,8 +47,37 @@ export function useNewForm() {var _ref = arguments.length > 0 && arguments[0] !=
45
47
  });
46
48
  };
47
49
 
50
+ var markTouched = function markTouched(name) {
51
+ touchedRef.current.add(toKey(name));
52
+ };
53
+
54
+ var updateDirty = function updateDirty(name) {
55
+ var key = toKey(name);
56
+ var current = path(toPath(name), valuesRef.current);
57
+ var initial = path(toPath(name), initialValuesRef.current);
58
+ if (current === initial) {
59
+ dirtyRef.current.delete(key);
60
+ } else {
61
+ dirtyRef.current.add(key);
62
+ }
63
+ };
64
+
65
+ var isTouched = function isTouched(name) {
66
+ if (!name) return touchedRef.current.size > 0;
67
+ return touchedRef.current.has(toKey(name));
68
+ };
69
+
70
+ var isDirty = function isDirty(name) {
71
+ if (!name) return dirtyRef.current.size > 0;
72
+ return dirtyRef.current.has(toKey(name));
73
+ };
74
+
75
+ var getTouchedFields = function getTouchedFields() {return _toConsumableArray(touchedRef.current);};
76
+ var getDirtyFields = function getDirtyFields() {return _toConsumableArray(dirtyRef.current);};
77
+
48
78
  var setFieldValue = function setFieldValue(name, value) {
49
79
  valuesRef.current = assocPath(toPath(name), value, valuesRef.current);
80
+ updateDirty(name);
50
81
  notify(name);
51
82
  var fn = callbacksRef.current.onValuesChange;
52
83
  if (fn) fn(name, valuesRef.current);
@@ -69,6 +100,8 @@ export function useNewForm() {var _ref = arguments.length > 0 && arguments[0] !=
69
100
  var resetFields = function resetFields() {
70
101
  valuesRef.current = Object.assign({}, initialValuesRef.current);
71
102
  errorsRef.current = {};
103
+ touchedRef.current.clear();
104
+ dirtyRef.current.clear();
72
105
  notifyAll();
73
106
  notifyAllErrors();
74
107
  };
@@ -196,6 +229,11 @@ export function useNewForm() {var _ref = arguments.length > 0 && arguments[0] !=
196
229
  getError: getError,
197
230
  setError: setError,
198
231
  clearErrors: clearErrors,
232
+ markTouched: markTouched,
233
+ isTouched: isTouched,
234
+ isDirty: isDirty,
235
+ getTouchedFields: getTouchedFields,
236
+ getDirtyFields: getDirtyFields,
199
237
  registerListener: registerListener,
200
238
  registerErrorListener: registerErrorListener,
201
239
  registerRules: registerRules,
@@ -2,4 +2,6 @@ export * from "./debounce";
2
2
  export * from "./string";
3
3
  export * from "./random";
4
4
  export * from "./storage";
5
+ export * from "./weekStart";
6
+ export * from "./weekStartSetup";
5
7
  export * from "./../abstractions/helpers/useSafeAreaInsets";
@@ -0,0 +1,25 @@
1
+ import dayjs from 'dayjs';
2
+ import updateLocale from 'dayjs/esm/plugin/updateLocale';
3
+
4
+ dayjs.extend(updateLocale);
5
+
6
+ var _override = null;
7
+
8
+ export function getFirstDayOfWeek() {
9
+ if (_override !== null) return _override;
10
+ return dayjs().$locale().weekStart || 0;
11
+ }
12
+
13
+ export function setFirstDayOfWeek(day) {
14
+ _override = day;
15
+ dayjs.updateLocale(dayjs().$locale().name || 'en', { weekStart: day });
16
+ }
17
+
18
+ export function getOrderedWeekdays() {
19
+ var first = getFirstDayOfWeek();
20
+ return Array.from({ length: 7 }, function (_, i) {return (first + i) % 7;});
21
+ }
22
+
23
+ export function getWeekdayOffset(dayIndex) {
24
+ return (dayIndex - getFirstDayOfWeek() + 7) % 7;
25
+ }
@@ -0,0 +1,11 @@
1
+ import { setFirstDayOfWeek } from "./weekStart";
2
+
3
+ export function initFirstDayOfWeek() {
4
+ try {var _locale$weekInfo;
5
+ var locale = new Intl.Locale(navigator.language);
6
+ var weekInfo = (_locale$weekInfo = locale.weekInfo) != null ? _locale$weekInfo : locale.getWeekInfo == null ? void 0 : locale.getWeekInfo();
7
+ if ((weekInfo == null ? void 0 : weekInfo.firstDay) != null) {
8
+ setFirstDayOfWeek(weekInfo.firstDay === 7 ? 0 : weekInfo.firstDay);
9
+ }
10
+ } catch (_unused) {}
11
+ }
@@ -0,0 +1,11 @@
1
+ import { setFirstDayOfWeek } from "./weekStart";
2
+
3
+ export function initFirstDayOfWeek() {
4
+ try {
5
+ var Localization = require('expo-localization');
6
+ var cal = Localization.getCalendars()[0];
7
+ if ((cal == null ? void 0 : cal.firstWeekday) != null) {
8
+ setFirstDayOfWeek((cal.firstWeekday - 1) % 7);
9
+ }
10
+ } catch (_unused) {}
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neko-os/ui",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "author": "Christian Storch <ccstorch@gmail.com>",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
package/src/NekoUI.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { initFirstDayOfWeek } from './helpers/weekStartSetup'
1
2
  import { DynamicStyleTag } from './DynamicStyleTag'
2
3
  import { I18nProvider } from './i18n'
3
4
  import { ModalsHandler } from './components/modals/modal/handler/ModalsHandler'
@@ -9,6 +10,8 @@ import { ThemeHandler } from './theme/ThemeHandler'
9
10
  import { ThemePickerDrawer } from './components/theme'
10
11
  import { useThemeHandler } from './theme'
11
12
 
13
+ initFirstDayOfWeek()
14
+
12
15
  export function NekoUI({ children, i18n, ...props }) {
13
16
  return (
14
17
  <ThemeHandler {...props}>
@@ -37,6 +37,7 @@ export function Dropdown({ items, ...rootProps }) {
37
37
  placement,
38
38
  gap,
39
39
  useBottomDrawer,
40
+ snapPoints,
40
41
  ...props
41
42
  } = formattedProps
42
43
 
@@ -52,6 +53,7 @@ export function Dropdown({ items, ...rootProps }) {
52
53
  // In case its web use the Drawer component
53
54
  contentProps={{ padding: 0 }}
54
55
  useBottomDrawer={useBottomDrawer}
56
+ snapPoints={snapPoints}
55
57
  {...popoverProps}
56
58
  renderContent={({ onClose }) => {
57
59
  const handleChange = (...params) => {
@@ -0,0 +1,176 @@
1
+ import React from 'react'
2
+ import dayjs from 'dayjs'
3
+ import quarterOfYear from 'dayjs/esm/plugin/quarterOfYear'
4
+
5
+ import { InfiniteCarousel } from '../carousel/InfiniteCarousel'
6
+ import { Link } from '../actions/Link'
7
+ import { Text } from '../text/Text'
8
+ import { View } from '../structure/View'
9
+ import { isDateDisabled } from './_helpers/dateDisabled'
10
+
11
+ dayjs.extend(quarterOfYear)
12
+
13
+ function getWeekEpoch() {
14
+ return dayjs('2000-01-01').startOf('week')
15
+ }
16
+
17
+ const TYPES = {
18
+ day: {
19
+ count: 7,
20
+ unit: 'day',
21
+ toPageValue(date) {
22
+ return date.startOf('week').diff(getWeekEpoch(), 'week')
23
+ },
24
+ getItems(pageValue) {
25
+ const weekStart = getWeekEpoch().add(pageValue, 'week')
26
+ return Array.from({ length: 7 }, (_, i) => {
27
+ const d = weekStart.add(i, 'day')
28
+ return { key: d.valueOf(), date: d, label: d.format('ddd'), sublabel: String(d.date()) }
29
+ })
30
+ },
31
+ },
32
+ week: {
33
+ count: 7,
34
+ unit: 'week',
35
+ toPageValue(date) {
36
+ const weekIndex = date.startOf('week').diff(getWeekEpoch(), 'week')
37
+ return Math.floor(weekIndex / 7)
38
+ },
39
+ getItems(pageValue) {
40
+ return Array.from({ length: 7 }, (_, i) => {
41
+ const weekIndex = pageValue * 7 + i
42
+ const d = getWeekEpoch().add(weekIndex, 'week')
43
+ const end = d.add(6, 'day')
44
+ return { key: d.valueOf(), date: d, label: `${d.date()}-${end.date()}`, sublabel: d.format('MMM') }
45
+ })
46
+ },
47
+ },
48
+ month: {
49
+ count: 7,
50
+ unit: 'month',
51
+ toPageValue(date) {
52
+ const absMonth = date.year() * 12 + date.month()
53
+ return Math.floor(absMonth / 7)
54
+ },
55
+ getItems(pageValue) {
56
+ return Array.from({ length: 7 }, (_, i) => {
57
+ const absMonth = pageValue * 7 + i
58
+ const year = Math.floor(absMonth / 12)
59
+ const month = absMonth % 12
60
+ const d = dayjs().year(year).month(month).startOf('month')
61
+ return { key: d.valueOf(), date: d, label: d.format('MMM'), sublabel: d.format("'YY") }
62
+ })
63
+ },
64
+ },
65
+ quarter: {
66
+ count: 4,
67
+ unit: 'quarter',
68
+ toPageValue(date) {
69
+ return date.year()
70
+ },
71
+ getItems(pageValue) {
72
+ return Array.from({ length: 4 }, (_, i) => {
73
+ const d = dayjs().year(pageValue).month(i * 3).startOf('month')
74
+ return { key: d.valueOf(), date: d, label: `Q${i + 1}`, sublabel: String(pageValue) }
75
+ })
76
+ },
77
+ },
78
+ year: {
79
+ count: 7,
80
+ unit: 'year',
81
+ toPageValue(date) {
82
+ return Math.floor(date.year() / 7)
83
+ },
84
+ getItems(pageValue) {
85
+ return Array.from({ length: 7 }, (_, i) => {
86
+ const year = pageValue * 7 + i
87
+ const d = dayjs().year(year).startOf('year')
88
+ return { key: d.valueOf(), date: d, label: String(year), sublabel: null }
89
+ })
90
+ },
91
+ },
92
+ }
93
+
94
+ const PeriodSlide = React.memo(function PeriodSlide({ items, value, unit, onChange, min, max, onCheckDisabled }) {
95
+ return (
96
+ <View row center gap="xs">
97
+ {items.map((item) => {
98
+ const isActive = !!value && dayjs(value).isSame(item.date, unit)
99
+ const disabled = isDateDisabled(item.date, { min, max, onCheckDisabled })
100
+
101
+ return (
102
+ <Link
103
+ key={item.key}
104
+ flex
105
+ center
106
+ br="md"
107
+ paddingV="xs"
108
+ onPress={() => onChange(item.date)}
109
+ bg={isActive && 'primary'}
110
+ disabled={disabled}
111
+ >
112
+ <Text sm center strong={isActive} text2={!isActive}>
113
+ {item.label}
114
+ </Text>
115
+ {item.sublabel && (
116
+ <Text xxs center text4={!isActive} strong={isActive}>
117
+ {item.sublabel}
118
+ </Text>
119
+ )}
120
+ </Link>
121
+ )
122
+ })}
123
+ </View>
124
+ )
125
+ })
126
+
127
+ export function PeriodNavBar({ type = 'day', value, onChange, min, max, onCheckDisabled, ...props }) {
128
+ const config = TYPES[type]
129
+ const [localValue, setLocalValue] = React.useState(value)
130
+ const resolvedValue = value === undefined ? localValue : value
131
+
132
+ const [currentPage, setCurrentPage] = React.useState(() => {
133
+ const date = resolvedValue ? dayjs(resolvedValue) : dayjs()
134
+ return config.toPageValue(date)
135
+ })
136
+
137
+ React.useEffect(() => {
138
+ const date = resolvedValue ? dayjs(resolvedValue) : dayjs()
139
+ setCurrentPage(TYPES[type].toPageValue(date))
140
+ }, [resolvedValue, type])
141
+
142
+ const handleSelect = React.useCallback(
143
+ (date) => {
144
+ setLocalValue(date)
145
+ onChange?.(date)
146
+ },
147
+ [onChange]
148
+ )
149
+
150
+ const minPage = min ? config.toPageValue(dayjs(min)) : undefined
151
+ const maxPage = max ? config.toPageValue(dayjs(max)) : undefined
152
+
153
+ const renderSlide = (pageValue) => (
154
+ <PeriodSlide
155
+ items={config.getItems(pageValue)}
156
+ value={resolvedValue}
157
+ unit={config.unit}
158
+ onChange={handleSelect}
159
+ min={min}
160
+ max={max}
161
+ onCheckDisabled={onCheckDisabled}
162
+ />
163
+ )
164
+
165
+ return (
166
+ <View className="neko-period-nav-bar" {...props}>
167
+ <InfiniteCarousel
168
+ value={currentPage}
169
+ onChange={setCurrentPage}
170
+ renderSlide={renderSlide}
171
+ min={minPage}
172
+ max={maxPage}
173
+ />
174
+ </View>
175
+ )
176
+ }
@@ -1,12 +1,16 @@
1
1
  import { Text } from '../text/Text'
2
2
  import { View } from '../structure/View'
3
+ import { getFirstDayOfWeek } from '../../helpers/weekStart'
3
4
 
4
- const weekdayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
5
+ const ALL_DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
5
6
 
6
7
  export function WeekDaysBar() {
8
+ const firstDay = getFirstDayOfWeek()
9
+ const labels = [...ALL_DAYS.slice(firstDay), ...ALL_DAYS.slice(0, firstDay)]
10
+
7
11
  return (
8
12
  <View className="neko-week-days-bar" row center gap="sm">
9
- {weekdayLabels.map((w) => (
13
+ {labels.map((w) => (
10
14
  <View key={w} flex height={30} center>
11
15
  <Text center sm text4>
12
16
  {w}
@@ -1,13 +1,17 @@
1
1
  import dayjs from 'dayjs'
2
2
  import React from 'react'
3
3
 
4
+ import { getFirstDayOfWeek } from '../../../helpers/weekStart'
5
+
4
6
  export function useCalendarDays(currentMonth) {
5
7
  return React.useMemo(() => {
6
8
  if (!currentMonth?.isValid?.()) currentMonth = dayjs()
7
9
  const startWeekday = currentMonth.startOf('month').day()
10
+ const firstDay = getFirstDayOfWeek()
11
+ const offset = (startWeekday - firstDay + 7) % 7
8
12
  const daysInMonth = currentMonth.daysInMonth()
9
13
 
10
- const blanks = Array.from({ length: startWeekday }, () => null)
14
+ const blanks = Array.from({ length: offset }, () => null)
11
15
  const days = Array.from({ length: daysInMonth }, (_, i) => i + 1)
12
16
  const cells = [...blanks, ...days]
13
17
 
@@ -1 +1 @@
1
- // export * from './DayPicker'
1
+ export * from './PeriodNavBar'
@@ -33,7 +33,7 @@ function formatValue(value, type) {
33
33
  case 'month':
34
34
  return [date.startOf('month'), date.endOf('month')]
35
35
  case 'week':
36
- return [date.startOf('isoWeek'), date.endOf('isoWeek')]
36
+ return [date.startOf('week'), date.endOf('week')]
37
37
  default:
38
38
  return [date.startOf('day'), date.endOf('day')]
39
39
  }
@@ -62,6 +62,7 @@ export function FormItem({
62
62
 
63
63
  const handleBlur = (e, originalOnBlur) => {
64
64
  if (originalOnBlur) originalOnBlur(e)
65
+ form.markTouched(listPath)
65
66
 
66
67
  if (shouldValidateOn('onBlur', rules, validateTrigger)) {
67
68
  form.validateField(listPath, 'onBlur')
@@ -6,6 +6,8 @@ export function useNewForm({ initialValues = {}, validate, onSubmit, onValuesCha
6
6
  const valuesRef = React.useRef({ ...initialValues })
7
7
  const initialValuesRef = React.useRef({ ...initialValues })
8
8
  const errorsRef = React.useRef({}) // Flat structure: { 'users': 'error', 'users.0.name': 'error' }
9
+ const touchedRef = React.useRef(new Set())
10
+ const dirtyRef = React.useRef(new Set())
9
11
  const listenersRef = React.useRef({})
10
12
  const errorListenersRef = React.useRef({})
11
13
  const rulesRegistryRef = React.useRef(new Map())
@@ -45,8 +47,37 @@ export function useNewForm({ initialValues = {}, validate, onSubmit, onValuesCha
45
47
  })
46
48
  }
47
49
 
50
+ const markTouched = (name) => {
51
+ touchedRef.current.add(toKey(name))
52
+ }
53
+
54
+ const updateDirty = (name) => {
55
+ const key = toKey(name)
56
+ const current = path(toPath(name), valuesRef.current)
57
+ const initial = path(toPath(name), initialValuesRef.current)
58
+ if (current === initial) {
59
+ dirtyRef.current.delete(key)
60
+ } else {
61
+ dirtyRef.current.add(key)
62
+ }
63
+ }
64
+
65
+ const isTouched = (name) => {
66
+ if (!name) return touchedRef.current.size > 0
67
+ return touchedRef.current.has(toKey(name))
68
+ }
69
+
70
+ const isDirty = (name) => {
71
+ if (!name) return dirtyRef.current.size > 0
72
+ return dirtyRef.current.has(toKey(name))
73
+ }
74
+
75
+ const getTouchedFields = () => [...touchedRef.current]
76
+ const getDirtyFields = () => [...dirtyRef.current]
77
+
48
78
  const setFieldValue = (name, value) => {
49
79
  valuesRef.current = assocPath(toPath(name), value, valuesRef.current)
80
+ updateDirty(name)
50
81
  notify(name)
51
82
  const fn = callbacksRef.current.onValuesChange
52
83
  if (fn) fn(name, valuesRef.current)
@@ -69,6 +100,8 @@ export function useNewForm({ initialValues = {}, validate, onSubmit, onValuesCha
69
100
  const resetFields = () => {
70
101
  valuesRef.current = { ...initialValuesRef.current }
71
102
  errorsRef.current = {}
103
+ touchedRef.current.clear()
104
+ dirtyRef.current.clear()
72
105
  notifyAll()
73
106
  notifyAllErrors()
74
107
  }
@@ -196,6 +229,11 @@ export function useNewForm({ initialValues = {}, validate, onSubmit, onValuesCha
196
229
  getError,
197
230
  setError,
198
231
  clearErrors,
232
+ markTouched,
233
+ isTouched,
234
+ isDirty,
235
+ getTouchedFields,
236
+ getDirtyFields,
199
237
  registerListener,
200
238
  registerErrorListener,
201
239
  registerRules,
@@ -2,4 +2,6 @@ export * from './debounce'
2
2
  export * from './string'
3
3
  export * from './random'
4
4
  export * from './storage'
5
+ export * from './weekStart'
6
+ export * from './weekStartSetup'
5
7
  export * from './../abstractions/helpers/useSafeAreaInsets'
@@ -0,0 +1,25 @@
1
+ import dayjs from 'dayjs'
2
+ import updateLocale from 'dayjs/esm/plugin/updateLocale'
3
+
4
+ dayjs.extend(updateLocale)
5
+
6
+ let _override = null
7
+
8
+ export function getFirstDayOfWeek() {
9
+ if (_override !== null) return _override
10
+ return dayjs().$locale().weekStart || 0
11
+ }
12
+
13
+ export function setFirstDayOfWeek(day) {
14
+ _override = day
15
+ dayjs.updateLocale(dayjs().$locale().name || 'en', { weekStart: day })
16
+ }
17
+
18
+ export function getOrderedWeekdays() {
19
+ const first = getFirstDayOfWeek()
20
+ return Array.from({ length: 7 }, (_, i) => (first + i) % 7)
21
+ }
22
+
23
+ export function getWeekdayOffset(dayIndex) {
24
+ return (dayIndex - getFirstDayOfWeek() + 7) % 7
25
+ }
@@ -0,0 +1,11 @@
1
+ import { setFirstDayOfWeek } from './weekStart'
2
+
3
+ export function initFirstDayOfWeek() {
4
+ try {
5
+ const locale = new Intl.Locale(navigator.language)
6
+ const weekInfo = locale.weekInfo ?? locale.getWeekInfo?.()
7
+ if (weekInfo?.firstDay != null) {
8
+ setFirstDayOfWeek(weekInfo.firstDay === 7 ? 0 : weekInfo.firstDay)
9
+ }
10
+ } catch {}
11
+ }
@@ -0,0 +1,11 @@
1
+ import { setFirstDayOfWeek } from './weekStart'
2
+
3
+ export function initFirstDayOfWeek() {
4
+ try {
5
+ const Localization = require('expo-localization')
6
+ const cal = Localization.getCalendars()[0]
7
+ if (cal?.firstWeekday != null) {
8
+ setFirstDayOfWeek((cal.firstWeekday - 1) % 7)
9
+ }
10
+ } catch {}
11
+ }