react-native-molecules 0.5.0-beta.10 → 0.5.0-beta.11

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.
@@ -125,7 +125,7 @@ const TouchableRipple = (
125
125
  ref: any,
126
126
  ) => {
127
127
  // TODO - enable ripple onLongPress, need to check for mobile as well
128
- const disabled = disabledProp || !onPress;
128
+ const disabled = disabledProp;
129
129
 
130
130
  const componentStyles = touchableRippleStyles;
131
131
 
package/hooks/index.tsx CHANGED
@@ -18,11 +18,6 @@ export { useMediaQuery } from './useMediaQuery';
18
18
  export { useMergedRefs } from './useMergedRefs';
19
19
  export { default as usePrevious } from './usePrevious';
20
20
  export * from './useQueryFilter';
21
- export {
22
- default as useSearchable,
23
- type UseSearchableProps,
24
- useSearchInputProps,
25
- } from './useSearchable';
26
21
  export { default as useSubcomponents, type UseSubcomponentsProps } from './useSubcomponents';
27
22
  export * from './useTheme';
28
23
  export { default as useToggle } from './useToggle';
@@ -6,7 +6,7 @@ export type UseSubcomponentsProps<T extends string> = {
6
6
  /**
7
7
  * array of displayName as string
8
8
  * */
9
- allowedChildren: T[];
9
+ allowedChildren: (T | { name: T; allowMultiple?: boolean })[];
10
10
  /**
11
11
  * If true, also returns the remaining children that don't match any of the allowedChildren
12
12
  * in a `rest` property
@@ -44,49 +44,47 @@ function useSubcomponents<T extends string = string, IncludeRest extends boolean
44
44
  IncludeRest
45
45
  > {
46
46
  return useMemo(() => {
47
- // this will create properties with default empty array values even if they don't exist in the children
48
- const defaultContext = allowedChildren.reduce(
49
- (context, childName) => {
50
- return {
51
- ...context,
52
- [childName]: [],
53
- };
54
- },
55
- includeRest ? { rest: [] as ReactNode[] } : {},
56
- ) as UseSubcomponentsResult<T, IncludeRest>;
47
+ const configs = allowedChildren.map(entry =>
48
+ typeof entry === 'string'
49
+ ? { name: entry, allowMultiple: true as boolean }
50
+ : { name: entry.name, allowMultiple: entry.allowMultiple ?? true },
51
+ );
57
52
 
58
- const childArray = Children.toArray(children);
53
+ const nameSet = new Set(configs.map(c => c.name));
54
+ const allowMultipleMap = new Map(configs.map(c => [c.name, c.allowMultiple]));
59
55
 
60
- return childArray.reduce((context, child) => {
56
+ const result = configs.reduce((acc, { name }) => {
57
+ (acc as any)[name] = [];
58
+ return acc;
59
+ }, (includeRest ? { rest: [] } : {}) as UseSubcomponentsResult<T, IncludeRest>);
60
+
61
+ Children.forEach(children, child => {
61
62
  if (!isValidElement(child)) {
62
- // Non-element children go to rest if includeRest is enabled
63
63
  if (includeRest) {
64
- return {
65
- ...context,
66
- rest: [...(context as any).rest, child],
67
- };
64
+ (result as any).rest.push(child);
68
65
  }
69
- return context;
66
+ return;
70
67
  }
71
68
 
72
- const displayName = (child.type as FC)?.displayName as string | undefined;
69
+ const displayName = (child.type as FC)?.displayName as T | undefined;
73
70
 
74
- if (!displayName || !allowedChildren.includes(displayName as T)) {
75
- // Unmatched elements go to rest if includeRest is enabled
76
- if (includeRest) {
77
- return {
78
- ...context,
79
- rest: [...(context as any).rest, child],
80
- };
71
+ if (displayName && nameSet.has(displayName)) {
72
+ if (allowMultipleMap.get(displayName)) {
73
+ (result as any)[displayName].push(child);
74
+ } else {
75
+ // Only keep the last matching child
76
+ (result as any)[displayName] = [child];
81
77
  }
82
- return context;
78
+
79
+ return;
80
+ }
81
+
82
+ if (includeRest) {
83
+ (result as any).rest.push(child);
83
84
  }
85
+ });
84
86
 
85
- return {
86
- ...context,
87
- [displayName]: [...(context as any)[displayName], child],
88
- };
89
- }, defaultContext);
87
+ return result;
90
88
  }, [allowedChildren, children, includeRest]);
91
89
  }
92
90
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-molecules",
3
- "version": "0.5.0-beta.10",
3
+ "version": "0.5.0-beta.11",
4
4
  "author": "Thet Aung <thetaung.dev@gmail.com>",
5
5
  "license": "MIT",
6
6
  "main": "index.ts",
@@ -56,7 +56,7 @@
56
56
  "react": "19.1.0",
57
57
  "react-native": "0.81.4",
58
58
  "react-native-svg": ">=12.1.0",
59
- "react-native-unistyles": "^3.0.15",
59
+ "react-native-unistyles": "^3.0.22",
60
60
  "react-native-web": "~0.21.1",
61
61
  "react-native-reanimated": ">=4.0.0",
62
62
  "react-native-redash": ">=18.0.0"
@@ -73,7 +73,7 @@
73
73
  "react-native": "0.81.4",
74
74
  "react-native-builder-bob": "^0.17.1",
75
75
  "react-native-reanimated": "~4.1.1",
76
- "react-native-unistyles": "^3.0.15",
76
+ "react-native-unistyles": "^3.0.22",
77
77
  "react-native-web": "~0.21.1"
78
78
  },
79
79
  "eslintIgnore": [
@@ -1,74 +0,0 @@
1
- import { type ReactElement, useCallback, useMemo } from 'react';
2
-
3
- import { IconButton } from '../components/IconButton';
4
- import {
5
- TextInput,
6
- type TextInputElementProps,
7
- type TextInputProps,
8
- } from '../components/TextInput';
9
- import useControlledValue from './useControlledValue';
10
-
11
- export interface UseSearchableProps {
12
- searchable?: boolean;
13
- onQueryChange?: (search: string) => void;
14
- query?: string;
15
- searchInputProps?: Omit<TextInputProps, 'value' | 'onChangeText'>;
16
- }
17
-
18
- const useSearchInputProps = (props?: Partial<TextInputProps>) => {
19
- const onChange = props?.onChangeText;
20
- const onPressClear = useCallback(() => {
21
- onChange?.('');
22
- }, [onChange]);
23
-
24
- const right = useCallback(
25
- ({ color, forceFocus }: TextInputElementProps) => (
26
- <IconButton
27
- name={props?.value ? 'close-circle-outline' : 'magnify'}
28
- onPress={props?.value ? onPressClear : forceFocus}
29
- color={color}
30
- />
31
- ),
32
- [onPressClear, props?.value],
33
- );
34
-
35
- return useMemo(
36
- () => (props?.right === undefined ? props : { right, ...props }),
37
- [props, right],
38
- );
39
- };
40
-
41
- const useSearchable = ({
42
- searchable,
43
- onQueryChange,
44
- query,
45
- searchInputProps,
46
- }: UseSearchableProps = {}): ReactElement<TextInputProps> | null => {
47
- const [value, onValueChange] = useControlledValue({
48
- value: query || '',
49
- defaultValue: '', // to disable the useControlledValue inside TextInput
50
- onChange: onQueryChange,
51
- disabled: !searchable,
52
- });
53
-
54
- const props = useSearchInputProps(
55
- useMemo(
56
- () => ({
57
- ...searchInputProps,
58
- value,
59
- onChangeText: onValueChange,
60
- }),
61
- [onValueChange, searchInputProps, value],
62
- ),
63
- );
64
-
65
- return useMemo(() => {
66
- if (!searchable || !onQueryChange) return null;
67
-
68
- return <TextInput {...props} />;
69
- }, [onQueryChange, props, searchable]);
70
- };
71
-
72
- export { useSearchInputProps };
73
-
74
- export default useSearchable;