native-pytech 1.0.94 → 1.0.97

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 (48) hide show
  1. package/dist/libs/editPage/src/components/Item/index.d.ts +2 -3
  2. package/dist/libs/editPage/src/components/ItemDate/index.d.ts +2 -3
  3. package/dist/libs/editPage/src/components/ItemDate/index.ios.d.ts +1 -1
  4. package/dist/libs/editPage/src/components/ItemDate/index.ios.js +4 -5
  5. package/dist/libs/editPage/src/components/ItemDate/types.d.ts +4 -0
  6. package/dist/libs/editPage/src/components/TextField/index.d.ts +2 -3
  7. package/dist/libs/editPage/src/components/TextField/index.ios.d.ts +1 -1
  8. package/dist/libs/editPage/src/components/TextField/index.ios.js +10 -29
  9. package/dist/libs/editPage/src/components/TextField/types.d.ts +4 -0
  10. package/dist/libs/editPage/src/components/Wrapper/index.d.ts +1 -2
  11. package/dist/libs/editPage/src/components/Wrapper/index.js +42 -28
  12. package/dist/libs/editPage/src/components/Wrapper/types.d.ts +7 -11
  13. package/dist/libs/editPage/src/context/page.d.ts +5 -10
  14. package/dist/libs/editPage copy/index.d.ts +9 -0
  15. package/dist/libs/editPage copy/index.js +7 -0
  16. package/dist/libs/editPage copy/src/components/Item/index.d.ts +4 -0
  17. package/dist/libs/editPage copy/src/components/Item/index.ios.d.ts +4 -0
  18. package/dist/libs/editPage copy/src/components/Item/index.ios.js +12 -0
  19. package/dist/libs/editPage copy/src/components/Item/index.js +1 -0
  20. package/dist/libs/editPage copy/src/components/Item/types.d.ts +14 -0
  21. package/dist/libs/editPage copy/src/components/Item/types.js +1 -0
  22. package/dist/libs/editPage copy/src/components/ItemDate/index.d.ts +4 -0
  23. package/dist/libs/editPage copy/src/components/ItemDate/index.ios.d.ts +4 -0
  24. package/dist/libs/editPage copy/src/components/ItemDate/index.ios.js +26 -0
  25. package/dist/libs/editPage copy/src/components/ItemDate/index.js +1 -0
  26. package/dist/libs/editPage copy/src/components/ItemDate/types.d.ts +21 -0
  27. package/dist/libs/editPage copy/src/components/ItemDate/types.js +1 -0
  28. package/dist/libs/editPage copy/src/components/Screen/index.d.ts +4 -0
  29. package/dist/libs/editPage copy/src/components/Screen/index.ios.d.ts +4 -0
  30. package/dist/libs/editPage copy/src/components/Screen/index.ios.js +8 -0
  31. package/dist/libs/editPage copy/src/components/Screen/index.js +1 -0
  32. package/dist/libs/editPage copy/src/components/Screen/types.d.ts +27 -0
  33. package/dist/libs/editPage copy/src/components/Screen/types.js +1 -0
  34. package/dist/libs/editPage copy/src/components/TextField/index.d.ts +4 -0
  35. package/dist/libs/editPage copy/src/components/TextField/index.ios.d.ts +4 -0
  36. package/dist/libs/editPage copy/src/components/TextField/index.ios.js +52 -0
  37. package/dist/libs/editPage copy/src/components/TextField/index.js +1 -0
  38. package/dist/libs/editPage copy/src/components/TextField/types.d.ts +28 -0
  39. package/dist/libs/editPage copy/src/components/TextField/types.js +1 -0
  40. package/dist/libs/editPage copy/src/components/Wrapper/index.d.ts +5 -0
  41. package/dist/libs/editPage copy/src/components/Wrapper/index.js +70 -0
  42. package/dist/libs/editPage copy/src/components/Wrapper/types.d.ts +27 -0
  43. package/dist/libs/editPage copy/src/components/Wrapper/types.js +1 -0
  44. package/dist/libs/editPage copy/src/context/page.d.ts +18 -0
  45. package/dist/libs/editPage copy/src/context/page.js +2 -0
  46. package/package.json +1 -1
  47. /package/dist/libs/{editPage → editPage copy}/src/context/item.d.ts +0 -0
  48. /package/dist/libs/{editPage → editPage copy}/src/context/item.js +0 -0
@@ -1,4 +1,3 @@
1
- declare const _default: ({ ...props }: {
2
- [x: string]: any;
3
- }) => any;
1
+ import type Props from './types';
2
+ declare const _default: ({ ...props }: Props) => any;
4
3
  export default _default;
@@ -1,4 +1,3 @@
1
- declare const _default: ({ ...props }: {
2
- [x: string]: any;
3
- }) => any;
1
+ import type Props from './types';
2
+ declare const _default: ({ ...props }: Props) => any;
4
3
  export default _default;
@@ -1,4 +1,4 @@
1
1
  import React from 'react';
2
2
  import type Props from './types';
3
- declare const _default: React.MemoExoticComponent<({ label, defaultValue, minDate, maxDate }: Props) => React.JSX.Element>;
3
+ declare const _default: React.MemoExoticComponent<({ itemKey, label, defaultValue, minDate, maxDate, }: Props) => React.JSX.Element>;
4
4
  export default _default;
@@ -2,16 +2,15 @@ import { Section, DatePicker } from '@expo/ui/swift-ui';
2
2
  import React, { memo, useCallback, useEffect, useState } from 'react';
3
3
  import { environment } from '@expo/ui/swift-ui/modifiers';
4
4
  import { usePage } from '../../context/page';
5
- import { useItem } from '../../context/item';
6
- export default memo(({ label, defaultValue, minDate = new Date(new Date().setFullYear(new Date().getFullYear() - 100)), maxDate = new Date() }) => {
7
- const { store } = usePage();
8
- const { index } = useItem();
5
+ export default memo(({ itemKey, label, defaultValue, minDate = new Date(new Date().setFullYear(new Date().getFullYear() - 100)), maxDate = new Date(), }) => {
6
+ const { store, registerItem } = usePage();
7
+ const key = registerItem(itemKey);
9
8
  const [selection, setSelection] = useState(defaultValue);
10
9
  // Hooks
11
10
  useEffect(() => setSelection(defaultValue), [defaultValue]);
12
11
  const onValueChange = useCallback((value) => {
13
12
  setSelection(value);
14
- store.values[index].set({
13
+ store.values[key].set({
15
14
  value: value,
16
15
  hasChanged: value.getTime() !== defaultValue?.getTime(),
17
16
  isValid: true,
@@ -1,4 +1,8 @@
1
1
  type Props = {
2
+ /**
3
+ identification key of the item.
4
+ */
5
+ itemKey?: string;
2
6
  /**
3
7
  Title of the date picker.
4
8
  */
@@ -1,4 +1,3 @@
1
- declare const _default: ({ ...props }: {
2
- [x: string]: any;
3
- }) => any;
1
+ import type Props from './types';
2
+ declare const _default: ({ ...props }: Props) => any;
4
3
  export default _default;
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import type Props from './types';
3
- declare const _default: React.MemoExoticComponent<({ defaultValue, placeholder, keyboardType, autocapitalization, secureTextEntry, isValid, }: Props) => React.JSX.Element>;
3
+ declare const _default: React.MemoExoticComponent<({ itemKey, defaultValue, placeholder, keyboardType, autocapitalization, secureTextEntry, isValid, }: Props) => React.JSX.Element>;
4
4
  export default _default;
@@ -1,51 +1,32 @@
1
1
  import React, { useMemo, memo, useRef, useCallback, useEffect } from "react";
2
+ import { useValue } from "@legendapp/state/react";
2
3
  import { SecureField, TextField } from "@expo/ui/swift-ui";
3
4
  import { keyboardType as keyboardTypeModifier, submitLabel, textInputAutocapitalization, onSubmit } from '@expo/ui/swift-ui/modifiers';
4
5
  import { usePage } from '../../context/page';
5
- import { useItem } from '../../context/item';
6
- export default memo(({ defaultValue, placeholder, keyboardType, autocapitalization = true, secureTextEntry, isValid, }) => {
7
- const { store, isUniqueItem, saveEnabledRef, onPressSave, textFieldsRefs } = usePage();
8
- const { index, nextIndex } = useItem();
6
+ export default memo(({ itemKey, defaultValue, placeholder, keyboardType, autocapitalization = true, secureTextEntry, isValid, }) => {
7
+ const { store, registerItem, onSubmit: _onSubmit } = usePage();
8
+ const isUniqueItem = useValue(() => store.isUniqueItem.get());
9
9
  const ref = useRef(null);
10
- textFieldsRefs.current[index] = ref;
11
- useEffect(() => store.values[index].value.set(defaultValue), [defaultValue]);
10
+ const key = registerItem(itemKey, ref);
11
+ console.log(placeholder, 'key', key);
12
+ useEffect(() => store.values[key].value.set(defaultValue), [defaultValue]);
12
13
  // onChange
13
14
  const onValueChange = useCallback((value) => {
14
15
  const _value = value.trim() === '' ? null : value.trim();
15
- store.values[index].set({
16
+ store.values[key].set({
16
17
  value: _value,
17
18
  hasChanged: _value !== defaultValue,
18
19
  isValid: isValid?.(_value) ?? true,
19
20
  });
20
21
  }, []);
21
- const _onSubmit = useCallback(() => {
22
- // Guarda los cambios
23
- if (isUniqueItem) {
24
- const saveEnabled = saveEnabledRef.current;
25
- if (!saveEnabled)
26
- return;
27
- onPressSave();
28
- return;
29
- }
30
- // Va al siguiente campo
31
- if (!nextIndex)
32
- return;
33
- textFieldsRefs.current[nextIndex].current?.focus();
34
- }, []);
35
22
  // Props
36
23
  const modifiers = useMemo(() => [
37
24
  ...(isUniqueItem ? [submitLabel('done')] : []),
38
25
  ...(keyboardType ? [keyboardTypeModifier(keyboardType)] : []),
39
26
  ...(!autocapitalization ? [textInputAutocapitalization('never')] : []),
40
- onSubmit(_onSubmit),
27
+ onSubmit(() => _onSubmit(key)),
41
28
  ], [keyboardType, autocapitalization, isUniqueItem]);
42
- const props = {
43
- autoFocus: isUniqueItem,
44
- modifiers,
45
- placeholder,
46
- defaultValue,
47
- onValueChange,
48
- };
29
+ const props = { autoFocus: isUniqueItem, modifiers, placeholder, defaultValue, onValueChange };
49
30
  if (secureTextEntry)
50
31
  return <SecureField {...props} ref={ref}/>;
51
32
  return <TextField {...props} ref={ref}/>;
@@ -1,4 +1,8 @@
1
1
  type Props = {
2
+ /**
3
+ identification key of the text field.
4
+ */
5
+ itemKey?: string;
2
6
  /**
3
7
  Default value of the text field.
4
8
  */
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
2
  import Props from './types';
3
- declare function Component<T>({ data, renderItem, onSave, }: Props<T>): React.JSX.Element;
4
- declare const _default: typeof Component;
3
+ declare const _default: React.MemoExoticComponent<({ children, onSave }: Props) => React.JSX.Element>;
5
4
  export default _default;
@@ -1,46 +1,67 @@
1
1
  import { useObservable, useValue } from '@legendapp/state/react';
2
- import { Stack, useRouter } from 'expo-router';
2
+ import { Stack, router } from 'expo-router';
3
3
  import React, { memo, useCallback, useMemo, useRef } from 'react';
4
- import Hooks from '../../../../../libs/constants/hooks';
5
4
  import { Provider } from '../../context/page';
6
- import { Provider as ItemProvider } from '../../context/item';
7
5
  import Screen from '../Screen';
8
- function Component({ data = [], renderItem, onSave, }) {
9
- const router = useRouter();
10
- const saveEnabledRef = useRef(false);
6
+ export default memo(({ children, onSave }) => {
7
+ const textFieldsRefs = useRef({});
8
+ const indexRef = useRef(0);
11
9
  // Store
12
- const values = (data ?? []).reduce((acc, item, index) => {
13
- acc[index] = {
14
- value: undefined,
15
- hasChanged: false,
16
- isValid: true,
17
- };
18
- return acc;
19
- }, {});
20
10
  const store = useObservable({
21
- values: values,
11
+ values: {},
22
12
  saveEnabled: () => {
23
13
  const listValues = Object.values(store.values.get());
24
14
  const hasChanged = listValues.some(value => value.hasChanged);
25
15
  const allValid = listValues.every(value => value.isValid);
26
16
  return hasChanged && allValid;
27
17
  },
18
+ isUniqueItem: () => {
19
+ const listValues = Object.values(store.values.get());
20
+ return listValues.length === 1;
21
+ },
28
22
  });
29
23
  const saveEnabled = useValue(() => store.saveEnabled.get());
30
- Hooks.useEffectWithoutFirstRender(() => saveEnabledRef.current = saveEnabled, [saveEnabled]);
31
- const textFieldsRefs = useRef({});
32
24
  // onPress
33
25
  const onPressSave = useCallback(async () => {
34
26
  // Obtengo los valores del store
35
27
  const values = store.values.peek();
36
- const valuesToSave = Object.values(values).map(value => value.value ?? null);
28
+ const valuesToSave = Object.fromEntries(Object.entries(values).map(([key, value]) => [key, value.value ?? null]));
37
29
  // Llamo a la función onSave
38
30
  const result = await onSave?.(valuesToSave);
39
31
  if (result === false)
40
32
  return;
41
33
  router.back();
42
34
  }, [onSave, store.values]);
43
- const value = useMemo(() => ({ store, saveEnabledRef, onPressSave, isUniqueItem: (data?.length ?? 0) === 1, textFieldsRefs }), []);
35
+ // Register
36
+ const registerItem = (itemKey, ref) => {
37
+ const key = itemKey ?? indexRef.current;
38
+ indexRef.current++;
39
+ ref && (textFieldsRefs.current[key] = ref);
40
+ return key;
41
+ };
42
+ const next = (itemKey) => {
43
+ const keys = Object.keys(textFieldsRefs.current);
44
+ const index = keys.findIndex(key => key > itemKey);
45
+ if (index === -1)
46
+ return;
47
+ const nextKey = keys[index + 1];
48
+ if (!nextKey)
49
+ return;
50
+ textFieldsRefs.current[nextKey].current?.focus();
51
+ };
52
+ const onSubmit = async (itemKey) => {
53
+ console.log('onSubmit', 'itemKey', itemKey);
54
+ // Guarda los cambios
55
+ if (store.isUniqueItem.peek()) {
56
+ if (!saveEnabled)
57
+ return;
58
+ await onPressSave();
59
+ return;
60
+ }
61
+ // Va al siguiente campo
62
+ next(itemKey);
63
+ };
64
+ const value = useMemo(() => ({ store, onSubmit, registerItem }), []);
44
65
  return (<>
45
66
  <Stack.Toolbar placement="left">
46
67
  <Stack.Toolbar.Button onPress={() => router.back()}>
@@ -56,15 +77,8 @@ function Component({ data = [], renderItem, onSave, }) {
56
77
 
57
78
  <Screen>
58
79
  <Provider value={value}>
59
- {data.map((item, index) => {
60
- const nextIndex = index + 1;
61
- const value = { index, nextIndex: nextIndex < data.length ? nextIndex : undefined };
62
- return (<ItemProvider key={index} value={value}>
63
- {renderItem?.(item)}
64
- </ItemProvider>);
65
- })}
80
+ {children}
66
81
  </Provider>
67
82
  </Screen>
68
83
  </>);
69
- }
70
- export default memo(Component);
84
+ });
@@ -1,27 +1,23 @@
1
- type Props<T> = {
1
+ type Props = {
2
2
  /**
3
- The data items to be rendered inside the list.
4
- @default []
3
+ Children to be rendered inside the wrapper.
5
4
  */
6
- data?: T[];
7
- /**
8
- The function to render the item.
9
- */
10
- renderItem?: (item: T) => React.ReactNode;
5
+ children: React.ReactNode;
11
6
  /**
12
7
  Function to be called when the user saves the changes.
13
8
  If the function returns false, the user will not be redirected to the previous screen.
14
9
  */
15
- onSave?: (values: (string | null | Date)[]) => boolean | Promise<boolean>;
10
+ onSave?: (items: Record<string, string | null | Date>) => boolean | void | Promise<boolean | void>;
16
11
  };
17
12
  export type Value = {
18
- value: string | null | Date | undefined;
13
+ value?: string | null | Date;
19
14
  hasChanged: boolean;
20
15
  isValid: boolean;
21
16
  };
22
- export type Values = Record<number, Value>;
17
+ export type Values = Record<string, Value>;
23
18
  export type Store = {
24
19
  values: Values;
25
20
  saveEnabled: boolean;
21
+ isUniqueItem: boolean;
26
22
  };
27
23
  export default Props;
@@ -1,18 +1,13 @@
1
1
  import type { Observable } from '@legendapp/state';
2
- import { TextFieldRef } from '@expo/ui/swift-ui';
3
2
  import { RefObject } from 'react';
4
3
  import type { Store } from '../components/Wrapper/types';
5
- export type TextFieldsRefsType = Record<number, RefObject<TextFieldRef | null>>;
4
+ export type TextFieldsRefsType = Record<number | string, RefObject<any>>;
6
5
  export declare const Provider: import("react").Provider<{
7
6
  store: Observable<Store>;
8
- saveEnabledRef: RefObject<boolean>;
9
- onPressSave: () => Promise<void>;
10
- isUniqueItem: boolean;
11
- textFieldsRefs: RefObject<TextFieldsRefsType>;
7
+ registerItem: (itemKey?: string, ref?: RefObject<any>) => string | number;
8
+ onSubmit: (itemKey: string | number) => Promise<void>;
12
9
  }>, usePage: () => {
13
10
  store: Observable<Store>;
14
- saveEnabledRef: RefObject<boolean>;
15
- onPressSave: () => Promise<void>;
16
- isUniqueItem: boolean;
17
- textFieldsRefs: RefObject<TextFieldsRefsType>;
11
+ registerItem: (itemKey?: string, ref?: RefObject<any>) => string | number;
12
+ onSubmit: (itemKey: string | number) => Promise<void>;
18
13
  };
@@ -0,0 +1,9 @@
1
+ import Wrapper from './src/components/Wrapper';
2
+ import Item from './src/components/Item';
3
+ import ItemDate from './src/components/ItemDate';
4
+ type Component = typeof Wrapper & {
5
+ Item: typeof Item;
6
+ ItemDate: typeof ItemDate;
7
+ };
8
+ declare const Screen: Component;
9
+ export default Screen;
@@ -0,0 +1,7 @@
1
+ import Wrapper from './src/components/Wrapper';
2
+ import Item from './src/components/Item';
3
+ import ItemDate from './src/components/ItemDate';
4
+ const Screen = Wrapper;
5
+ Screen.Item = Item;
6
+ Screen.ItemDate = ItemDate;
7
+ export default Screen;
@@ -0,0 +1,4 @@
1
+ declare const _default: ({ ...props }: {
2
+ [x: string]: any;
3
+ }) => any;
4
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type Props from './types';
3
+ declare const _default: React.MemoExoticComponent<({ label, minLengthSpacer, ...textFieldProps }: Props) => React.JSX.Element>;
4
+ export default _default;
@@ -0,0 +1,12 @@
1
+ import { HStack, Spacer, Text } from '@expo/ui/swift-ui';
2
+ import React, { memo } from 'react';
3
+ import TextField from '../TextField';
4
+ export default memo(({ label, minLengthSpacer, ...textFieldProps }) => {
5
+ if (!label)
6
+ return <TextField {...textFieldProps}/>;
7
+ return (<HStack>
8
+ <Text>{label}</Text>
9
+ <Spacer minLength={minLengthSpacer}/>
10
+ <TextField {...textFieldProps}/>
11
+ </HStack>);
12
+ });
@@ -0,0 +1 @@
1
+ export default ({ ...props }) => null;
@@ -0,0 +1,14 @@
1
+ import type TextFieldProps from '../TextField/types';
2
+ type Props = TextFieldProps & {
3
+ /**
4
+ Text to display on the left of the text field.
5
+ If not provided, the item will be only a text field.
6
+ */
7
+ label?: string;
8
+ /**
9
+ Minimum length of the spacer between the title and the text field.
10
+ If the title is not provided, will not be displayed.
11
+ */
12
+ minLengthSpacer?: number;
13
+ };
14
+ export default Props;
@@ -0,0 +1,4 @@
1
+ declare const _default: ({ ...props }: {
2
+ [x: string]: any;
3
+ }) => any;
4
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type Props from './types';
3
+ declare const _default: React.MemoExoticComponent<({ label, defaultValue, minDate, maxDate }: Props) => React.JSX.Element>;
4
+ export default _default;
@@ -0,0 +1,26 @@
1
+ import { Section, DatePicker } from '@expo/ui/swift-ui';
2
+ import React, { memo, useCallback, useEffect, useState } from 'react';
3
+ import { environment } from '@expo/ui/swift-ui/modifiers';
4
+ import { usePage } from '../../context/page';
5
+ import { useItem } from '../../context/item';
6
+ export default memo(({ label, defaultValue, minDate = new Date(new Date().setFullYear(new Date().getFullYear() - 100)), maxDate = new Date() }) => {
7
+ const { store } = usePage();
8
+ const { index } = useItem();
9
+ const [selection, setSelection] = useState(defaultValue);
10
+ // Hooks
11
+ useEffect(() => setSelection(defaultValue), [defaultValue]);
12
+ const onValueChange = useCallback((value) => {
13
+ setSelection(value);
14
+ store.values[index].set({
15
+ value: value,
16
+ hasChanged: value.getTime() !== defaultValue?.getTime(),
17
+ isValid: true,
18
+ });
19
+ }, []);
20
+ return (<Section>
21
+ <DatePicker title={label} selection={selection} onDateChange={onValueChange} modifiers={[environment('locale', 'es_ES')]} range={{
22
+ start: minDate,
23
+ end: maxDate,
24
+ }}/>
25
+ </Section>);
26
+ });
@@ -0,0 +1 @@
1
+ export default ({ ...props }) => null;
@@ -0,0 +1,21 @@
1
+ type Props = {
2
+ /**
3
+ Title of the date picker.
4
+ */
5
+ label?: string;
6
+ /**
7
+ Default value of the date picker.
8
+ */
9
+ defaultValue?: Date;
10
+ /**
11
+ Minimum date allowed.
12
+ @default 100 years ago
13
+ */
14
+ minDate?: Date;
15
+ /**
16
+ Maximum date allowed.
17
+ @default today
18
+ */
19
+ maxDate?: Date;
20
+ };
21
+ export default Props;
@@ -0,0 +1,4 @@
1
+ declare const _default: ({ children }: {
2
+ children: React.ReactNode;
3
+ }) => any;
4
+ export default _default;
@@ -0,0 +1,4 @@
1
+ declare const _default: ({ children }: {
2
+ children: React.ReactNode;
3
+ }) => import("react").JSX.Element;
4
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import { Host, List, Section } from '@expo/ui/swift-ui';
2
+ export default ({ children }) => (<Host style={{ flex: 1 }}>
3
+ <List>
4
+ <Section>
5
+ {children}
6
+ </Section>
7
+ </List>
8
+ </Host>);
@@ -0,0 +1 @@
1
+ export default ({ children }) => null;
@@ -0,0 +1,27 @@
1
+ type Props<T> = {
2
+ /**
3
+ The data items to be rendered inside the list.
4
+ @default []
5
+ */
6
+ data?: T[];
7
+ /**
8
+ The function to render the item.
9
+ */
10
+ renderItem?: (item: T) => React.ReactNode;
11
+ /**
12
+ Function to be called when the user saves the changes.
13
+ If the function returns false, the user will not be redirected to the previous screen.
14
+ */
15
+ onSave?: (values: (string | null | Date)[]) => boolean | Promise<boolean>;
16
+ };
17
+ export type Value = {
18
+ value: string | null | Date | undefined;
19
+ hasChanged: boolean;
20
+ isValid: boolean;
21
+ };
22
+ export type Values = Record<number, Value>;
23
+ export type Store = {
24
+ values: Values;
25
+ saveEnabled: boolean;
26
+ };
27
+ export default Props;
@@ -0,0 +1,4 @@
1
+ declare const _default: ({ ...props }: {
2
+ [x: string]: any;
3
+ }) => any;
4
+ export default _default;
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import type Props from './types';
3
+ declare const _default: React.MemoExoticComponent<({ defaultValue, placeholder, keyboardType, autocapitalization, secureTextEntry, isValid, }: Props) => React.JSX.Element>;
4
+ export default _default;
@@ -0,0 +1,52 @@
1
+ import React, { useMemo, memo, useRef, useCallback, useEffect } from "react";
2
+ import { SecureField, TextField } from "@expo/ui/swift-ui";
3
+ import { keyboardType as keyboardTypeModifier, submitLabel, textInputAutocapitalization, onSubmit } from '@expo/ui/swift-ui/modifiers';
4
+ import { usePage } from '../../context/page';
5
+ import { useItem } from '../../context/item';
6
+ export default memo(({ defaultValue, placeholder, keyboardType, autocapitalization = true, secureTextEntry, isValid, }) => {
7
+ const { store, isUniqueItem, saveEnabledRef, onPressSave, textFieldsRefs } = usePage();
8
+ const { index, nextIndex } = useItem();
9
+ const ref = useRef(null);
10
+ textFieldsRefs.current[index] = ref;
11
+ useEffect(() => store.values[index].value.set(defaultValue), [defaultValue]);
12
+ // onChange
13
+ const onValueChange = useCallback((value) => {
14
+ const _value = value.trim() === '' ? null : value.trim();
15
+ store.values[index].set({
16
+ value: _value,
17
+ hasChanged: _value !== defaultValue,
18
+ isValid: isValid?.(_value) ?? true,
19
+ });
20
+ }, []);
21
+ const _onSubmit = useCallback(() => {
22
+ // Guarda los cambios
23
+ if (isUniqueItem) {
24
+ const saveEnabled = saveEnabledRef.current;
25
+ if (!saveEnabled)
26
+ return;
27
+ onPressSave();
28
+ return;
29
+ }
30
+ // Va al siguiente campo
31
+ if (!nextIndex)
32
+ return;
33
+ textFieldsRefs.current[nextIndex].current?.focus();
34
+ }, []);
35
+ // Props
36
+ const modifiers = useMemo(() => [
37
+ ...(isUniqueItem ? [submitLabel('done')] : []),
38
+ ...(keyboardType ? [keyboardTypeModifier(keyboardType)] : []),
39
+ ...(!autocapitalization ? [textInputAutocapitalization('never')] : []),
40
+ onSubmit(_onSubmit),
41
+ ], [keyboardType, autocapitalization, isUniqueItem]);
42
+ const props = {
43
+ autoFocus: isUniqueItem,
44
+ modifiers,
45
+ placeholder,
46
+ defaultValue,
47
+ onValueChange,
48
+ };
49
+ if (secureTextEntry)
50
+ return <SecureField {...props} ref={ref}/>;
51
+ return <TextField {...props} ref={ref}/>;
52
+ });
@@ -0,0 +1 @@
1
+ export default ({ ...props }) => null;
@@ -0,0 +1,28 @@
1
+ type Props = {
2
+ /**
3
+ Default value of the text field.
4
+ */
5
+ defaultValue?: string;
6
+ /**
7
+ Placeholder of the text field.
8
+ */
9
+ placeholder?: string;
10
+ /**
11
+ Keyboard type. Uses the keyboardType modifier.
12
+ */
13
+ keyboardType?: "default" | "email-address" | "numeric" | "phone-pad" | "ascii-capable" | "numbers-and-punctuation" | "url" | "name-phone-pad" | "decimal-pad" | "twitter" | "web-search" | "ascii-capable-number-pad";
14
+ /**
15
+ If true, the text field will be autocapitalized. Uses the textInputAutocapitalization modifier.
16
+ @default true
17
+ */
18
+ autocapitalization?: boolean;
19
+ /**
20
+ If true, the text field will be secure (password).
21
+ */
22
+ secureTextEntry?: boolean;
23
+ /**
24
+ Function to validate the value.
25
+ */
26
+ isValid?: (value: string | null) => boolean;
27
+ };
28
+ export default Props;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import Props from './types';
3
+ declare function Component<T>({ data, renderItem, onSave, }: Props<T>): React.JSX.Element;
4
+ declare const _default: typeof Component;
5
+ export default _default;
@@ -0,0 +1,70 @@
1
+ import { useObservable, useValue } from '@legendapp/state/react';
2
+ import { Stack, useRouter } from 'expo-router';
3
+ import React, { memo, useCallback, useMemo, useRef } from 'react';
4
+ import Hooks from '../../../../../libs/constants/hooks';
5
+ import { Provider } from '../../context/page';
6
+ import { Provider as ItemProvider } from '../../context/item';
7
+ import Screen from '../Screen';
8
+ function Component({ data = [], renderItem, onSave, }) {
9
+ const router = useRouter();
10
+ const saveEnabledRef = useRef(false);
11
+ // Store
12
+ const values = (data ?? []).reduce((acc, item, index) => {
13
+ acc[index] = {
14
+ value: undefined,
15
+ hasChanged: false,
16
+ isValid: true,
17
+ };
18
+ return acc;
19
+ }, {});
20
+ const store = useObservable({
21
+ values: values,
22
+ saveEnabled: () => {
23
+ const listValues = Object.values(store.values.get());
24
+ const hasChanged = listValues.some(value => value.hasChanged);
25
+ const allValid = listValues.every(value => value.isValid);
26
+ return hasChanged && allValid;
27
+ },
28
+ });
29
+ const saveEnabled = useValue(() => store.saveEnabled.get());
30
+ Hooks.useEffectWithoutFirstRender(() => saveEnabledRef.current = saveEnabled, [saveEnabled]);
31
+ const textFieldsRefs = useRef({});
32
+ // onPress
33
+ const onPressSave = useCallback(async () => {
34
+ // Obtengo los valores del store
35
+ const values = store.values.peek();
36
+ const valuesToSave = Object.values(values).map(value => value.value ?? null);
37
+ // Llamo a la función onSave
38
+ const result = await onSave?.(valuesToSave);
39
+ if (result === false)
40
+ return;
41
+ router.back();
42
+ }, [onSave, store.values]);
43
+ const value = useMemo(() => ({ store, saveEnabledRef, onPressSave, isUniqueItem: (data?.length ?? 0) === 1, textFieldsRefs }), []);
44
+ return (<>
45
+ <Stack.Toolbar placement="left">
46
+ <Stack.Toolbar.Button onPress={() => router.back()}>
47
+ <Stack.Toolbar.Icon sf="xmark"/>
48
+ </Stack.Toolbar.Button>
49
+ </Stack.Toolbar>
50
+
51
+ <Stack.Toolbar placement="right">
52
+ <Stack.Toolbar.Button disabled={!saveEnabled} variant="done" onPress={onPressSave}>
53
+ <Stack.Toolbar.Icon sf="checkmark"/>
54
+ </Stack.Toolbar.Button>
55
+ </Stack.Toolbar>
56
+
57
+ <Screen>
58
+ <Provider value={value}>
59
+ {data.map((item, index) => {
60
+ const nextIndex = index + 1;
61
+ const value = { index, nextIndex: nextIndex < data.length ? nextIndex : undefined };
62
+ return (<ItemProvider key={index} value={value}>
63
+ {renderItem?.(item)}
64
+ </ItemProvider>);
65
+ })}
66
+ </Provider>
67
+ </Screen>
68
+ </>);
69
+ }
70
+ export default memo(Component);
@@ -0,0 +1,27 @@
1
+ type Props<T> = {
2
+ /**
3
+ The data items to be rendered inside the list.
4
+ @default []
5
+ */
6
+ data?: T[];
7
+ /**
8
+ The function to render the item.
9
+ */
10
+ renderItem?: (item: T) => React.ReactNode;
11
+ /**
12
+ Function to be called when the user saves the changes.
13
+ If the function returns false, the user will not be redirected to the previous screen.
14
+ */
15
+ onSave?: (values: (string | null | Date)[]) => boolean | Promise<boolean>;
16
+ };
17
+ export type Value = {
18
+ value: string | null | Date | undefined;
19
+ hasChanged: boolean;
20
+ isValid: boolean;
21
+ };
22
+ export type Values = Record<number, Value>;
23
+ export type Store = {
24
+ values: Values;
25
+ saveEnabled: boolean;
26
+ };
27
+ export default Props;
@@ -0,0 +1,18 @@
1
+ import type { Observable } from '@legendapp/state';
2
+ import { TextFieldRef } from '@expo/ui/swift-ui';
3
+ import { RefObject } from 'react';
4
+ import type { Store } from '../components/Wrapper/types';
5
+ export type TextFieldsRefsType = Record<number, RefObject<TextFieldRef | null>>;
6
+ export declare const Provider: import("react").Provider<{
7
+ store: Observable<Store>;
8
+ saveEnabledRef: RefObject<boolean>;
9
+ onPressSave: () => Promise<void>;
10
+ isUniqueItem: boolean;
11
+ textFieldsRefs: RefObject<TextFieldsRefsType>;
12
+ }>, usePage: () => {
13
+ store: Observable<Store>;
14
+ saveEnabledRef: RefObject<boolean>;
15
+ onPressSave: () => Promise<void>;
16
+ isUniqueItem: boolean;
17
+ textFieldsRefs: RefObject<TextFieldsRefsType>;
18
+ };
@@ -0,0 +1,2 @@
1
+ import Utils from '../../../../libs/constants/utils';
2
+ export const [Provider, usePage] = Utils.createCtx();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-pytech",
3
- "version": "1.0.94",
3
+ "version": "1.0.97",
4
4
  "description": "Libreria de React Native Pytech",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",