react-native-mantine 0.7.0 → 0.9.0

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 (81) hide show
  1. package/README.md +37 -5
  2. package/lib/commonjs/components/Group/index.js.map +1 -1
  3. package/lib/commonjs/components/Radio/index.js +62 -6
  4. package/lib/commonjs/components/Radio/index.js.map +1 -1
  5. package/lib/commonjs/components/Switch/index.js +6 -2
  6. package/lib/commonjs/components/Switch/index.js.map +1 -1
  7. package/lib/commonjs/hooks/index.js +28 -0
  8. package/lib/commonjs/hooks/index.js.map +1 -0
  9. package/lib/commonjs/hooks/use-form/index.js +40 -0
  10. package/lib/commonjs/hooks/use-form/index.js.map +1 -0
  11. package/lib/commonjs/hooks/use-form/types.js +2 -0
  12. package/lib/commonjs/hooks/use-form/types.js.map +1 -0
  13. package/lib/commonjs/hooks/use-form/useForm.js +418 -0
  14. package/lib/commonjs/hooks/use-form/useForm.js.map +1 -0
  15. package/lib/commonjs/hooks/use-form/validators.js +135 -0
  16. package/lib/commonjs/hooks/use-form/validators.js.map +1 -0
  17. package/lib/commonjs/index.js +11 -0
  18. package/lib/commonjs/index.js.map +1 -1
  19. package/lib/module/components/Group/index.js.map +1 -1
  20. package/lib/module/components/Radio/index.js +64 -8
  21. package/lib/module/components/Radio/index.js.map +1 -1
  22. package/lib/module/components/Switch/index.js +6 -2
  23. package/lib/module/components/Switch/index.js.map +1 -1
  24. package/lib/module/hooks/index.js +5 -0
  25. package/lib/module/hooks/index.js.map +1 -0
  26. package/lib/module/hooks/use-form/index.js +6 -0
  27. package/lib/module/hooks/use-form/index.js.map +1 -0
  28. package/lib/module/hooks/use-form/types.js +2 -0
  29. package/lib/module/hooks/use-form/types.js.map +1 -0
  30. package/lib/module/hooks/use-form/useForm.js +414 -0
  31. package/lib/module/hooks/use-form/useForm.js.map +1 -0
  32. package/lib/module/hooks/use-form/validators.js +122 -0
  33. package/lib/module/hooks/use-form/validators.js.map +1 -0
  34. package/lib/module/index.js +1 -0
  35. package/lib/module/index.js.map +1 -1
  36. package/lib/typescript/commonjs/src/components/Group/index.d.ts +1 -0
  37. package/lib/typescript/commonjs/src/components/Group/index.d.ts.map +1 -1
  38. package/lib/typescript/commonjs/src/components/Radio/index.d.ts +22 -1
  39. package/lib/typescript/commonjs/src/components/Radio/index.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/src/components/Switch/index.d.ts +3 -3
  41. package/lib/typescript/commonjs/src/components/Switch/index.d.ts.map +1 -1
  42. package/lib/typescript/commonjs/src/hooks/index.d.ts +3 -0
  43. package/lib/typescript/commonjs/src/hooks/index.d.ts.map +1 -0
  44. package/lib/typescript/commonjs/src/hooks/use-form/index.d.ts +4 -0
  45. package/lib/typescript/commonjs/src/hooks/use-form/index.d.ts.map +1 -0
  46. package/lib/typescript/commonjs/src/hooks/use-form/types.d.ts +119 -0
  47. package/lib/typescript/commonjs/src/hooks/use-form/types.d.ts.map +1 -0
  48. package/lib/typescript/commonjs/src/hooks/use-form/useForm.d.ts +30 -0
  49. package/lib/typescript/commonjs/src/hooks/use-form/useForm.d.ts.map +1 -0
  50. package/lib/typescript/commonjs/src/hooks/use-form/validators.d.ts +41 -0
  51. package/lib/typescript/commonjs/src/hooks/use-form/validators.d.ts.map +1 -0
  52. package/lib/typescript/commonjs/src/index.d.ts +1 -0
  53. package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
  54. package/lib/typescript/module/src/components/Group/index.d.ts +1 -0
  55. package/lib/typescript/module/src/components/Group/index.d.ts.map +1 -1
  56. package/lib/typescript/module/src/components/Radio/index.d.ts +22 -1
  57. package/lib/typescript/module/src/components/Radio/index.d.ts.map +1 -1
  58. package/lib/typescript/module/src/components/Switch/index.d.ts +3 -3
  59. package/lib/typescript/module/src/components/Switch/index.d.ts.map +1 -1
  60. package/lib/typescript/module/src/hooks/index.d.ts +3 -0
  61. package/lib/typescript/module/src/hooks/index.d.ts.map +1 -0
  62. package/lib/typescript/module/src/hooks/use-form/index.d.ts +4 -0
  63. package/lib/typescript/module/src/hooks/use-form/index.d.ts.map +1 -0
  64. package/lib/typescript/module/src/hooks/use-form/types.d.ts +119 -0
  65. package/lib/typescript/module/src/hooks/use-form/types.d.ts.map +1 -0
  66. package/lib/typescript/module/src/hooks/use-form/useForm.d.ts +30 -0
  67. package/lib/typescript/module/src/hooks/use-form/useForm.d.ts.map +1 -0
  68. package/lib/typescript/module/src/hooks/use-form/validators.d.ts +41 -0
  69. package/lib/typescript/module/src/hooks/use-form/validators.d.ts.map +1 -0
  70. package/lib/typescript/module/src/index.d.ts +1 -0
  71. package/lib/typescript/module/src/index.d.ts.map +1 -1
  72. package/package.json +1 -1
  73. package/src/components/Group/index.tsx +1 -0
  74. package/src/components/Radio/index.tsx +99 -8
  75. package/src/components/Switch/index.tsx +10 -6
  76. package/src/hooks/index.ts +2 -0
  77. package/src/hooks/use-form/index.ts +3 -0
  78. package/src/hooks/use-form/types.ts +169 -0
  79. package/src/hooks/use-form/useForm.ts +436 -0
  80. package/src/hooks/use-form/validators.ts +143 -0
  81. package/src/index.tsx +1 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Form field validation function
3
+ */
4
+ export type FormValidator<T> = (value: T) => string | null;
5
+ /**
6
+ * Form validation rules
7
+ */
8
+ export type FormValidationRules<Values> = {
9
+ [K in keyof Values]?: FormValidator<Values[K]> | FormValidator<Values[K]>[];
10
+ };
11
+ /**
12
+ * Form errors
13
+ */
14
+ export type FormErrors<Values = Record<string, any>> = Partial<Record<keyof Values, string>>;
15
+ /**
16
+ * Form touched state
17
+ */
18
+ export type FormTouched<Values = Record<string, any>> = Partial<Record<keyof Values, boolean>>;
19
+ /**
20
+ * Form dirty state
21
+ */
22
+ export type FormDirty<Values = Record<string, any>> = Partial<Record<keyof Values, boolean>>;
23
+ /**
24
+ * Form field status
25
+ */
26
+ export interface FormFieldStatus {
27
+ hasError: boolean;
28
+ isTouched: boolean;
29
+ isDirty: boolean;
30
+ }
31
+ /**
32
+ * Props to be spread on input components
33
+ */
34
+ export interface FormInputProps<T = any> {
35
+ value: T;
36
+ onChange?: (value: T) => void;
37
+ onChangeText?: (text: string) => void;
38
+ error?: string;
39
+ onBlur?: () => void;
40
+ }
41
+ /**
42
+ * Form submit handler
43
+ */
44
+ export type FormSubmitHandler<Values> = (values: Values, event?: any) => void | Promise<void>;
45
+ /**
46
+ * useForm hook input parameters
47
+ */
48
+ export interface UseFormInput<Values = Record<string, any>> {
49
+ /** Initial form values */
50
+ initialValues?: Values;
51
+ /** Initial form errors */
52
+ initialErrors?: FormErrors<Values>;
53
+ /** Initial touched state */
54
+ initialTouched?: FormTouched<Values>;
55
+ /** Initial dirty state */
56
+ initialDirty?: FormDirty<Values>;
57
+ /** Form validation rules */
58
+ validate?: FormValidationRules<Values>;
59
+ /** Clear input error on change */
60
+ clearInputErrorOnChange?: boolean;
61
+ /** Validate input on change */
62
+ validateInputOnChange?: boolean;
63
+ /** Validate input on blur */
64
+ validateInputOnBlur?: boolean;
65
+ /** Transform values before submit */
66
+ transformValues?: (values: Values) => any;
67
+ }
68
+ /**
69
+ * useForm hook return type
70
+ */
71
+ export interface UseFormReturnType<Values = Record<string, any>> {
72
+ /** Current form values */
73
+ values: Values;
74
+ /** Current form errors */
75
+ errors: FormErrors<Values>;
76
+ /** Current touched state */
77
+ touched: FormTouched<Values>;
78
+ /** Current dirty state */
79
+ dirty: FormDirty<Values>;
80
+ /** Set a single field value */
81
+ setFieldValue: <K extends keyof Values>(field: K, value: Values[K]) => void;
82
+ /** Set multiple values */
83
+ setValues: (values: Partial<Values>) => void;
84
+ /** Set a single field error */
85
+ setFieldError: <K extends keyof Values>(field: K, error: string | null) => void;
86
+ /** Set multiple errors */
87
+ setErrors: (errors: FormErrors<Values>) => void;
88
+ /** Clear a specific field error */
89
+ clearFieldError: <K extends keyof Values>(field: K) => void;
90
+ /** Clear all errors */
91
+ clearErrors: () => void;
92
+ /** Reset form to initial values */
93
+ reset: () => void;
94
+ /** Validate a specific field */
95
+ validateField: <K extends keyof Values>(field: K) => boolean;
96
+ /** Validate entire form */
97
+ validate: () => boolean;
98
+ /** Check if form is valid */
99
+ isValid: () => boolean;
100
+ /** Check if form is dirty */
101
+ isDirty: () => boolean;
102
+ /** Get field status */
103
+ getFieldStatus: <K extends keyof Values>(field: K) => FormFieldStatus;
104
+ /** Get props to spread on input component */
105
+ getInputProps: <K extends keyof Values>(field: K, options?: {
106
+ type?: 'input' | 'checkbox' | 'radio' | 'select';
107
+ withError?: boolean;
108
+ withFocus?: boolean;
109
+ }) => FormInputProps<Values[K]>;
110
+ /** Handle form submit */
111
+ onSubmit: (handleSubmit: FormSubmitHandler<Values>) => (event?: any) => void | Promise<void>;
112
+ /** Reset touched state */
113
+ resetTouched: () => void;
114
+ /** Reset dirty state */
115
+ resetDirty: () => void;
116
+ /** Mark field as touched */
117
+ setFieldTouched: <K extends keyof Values>(field: K, touched?: boolean) => void;
118
+ }
119
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../src/hooks/use-form/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAAG,IAAI,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,MAAM,IAAI;KACvC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;CAC5E,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,CAC5D,MAAM,CAAC,MAAM,MAAM,EAAE,MAAM,CAAC,CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,CAC7D,MAAM,CAAC,MAAM,MAAM,EAAE,OAAO,CAAC,CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,OAAO,CAC3D,MAAM,CAAC,MAAM,MAAM,EAAE,OAAO,CAAC,CAC9B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,GAAG;IACrC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAC9B,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,MAAM,IAAI,CACtC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,GAAG,KACR,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,YAAY,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACxD,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAEnC,4BAA4B;IAC5B,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAErC,0BAA0B;IAC1B,YAAY,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAEjC,4BAA4B;IAC5B,QAAQ,CAAC,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAEvC,kCAAkC;IAClC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAElC,+BAA+B;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,6BAA6B;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,qCAAqC;IACrC,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,GAAG,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC7D,0BAA0B;IAC1B,MAAM,EAAE,MAAM,CAAC;IAEf,0BAA0B;IAC1B,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAE3B,4BAA4B;IAC5B,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAE7B,0BAA0B;IAC1B,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAEzB,+BAA+B;IAC/B,aAAa,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAE5E,0BAA0B;IAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAE7C,+BAA+B;IAC/B,aAAa,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAEhF,0BAA0B;IAC1B,SAAS,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IAEhD,mCAAmC;IACnC,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IAE5D,uBAAuB;IACvB,WAAW,EAAE,MAAM,IAAI,CAAC;IAExB,mCAAmC;IACnC,KAAK,EAAE,MAAM,IAAI,CAAC;IAElB,gCAAgC;IAChC,aAAa,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC;IAE7D,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,OAAO,CAAC;IAExB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,OAAO,CAAC;IAEvB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,OAAO,CAAC;IAEvB,uBAAuB;IACvB,cAAc,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,eAAe,CAAC;IAEtE,6CAA6C;IAC7C,aAAa,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EACpC,KAAK,EAAE,CAAC,EACR,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;QACjD,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,KACE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAE/B,yBAAyB;IACzB,QAAQ,EAAE,CACR,YAAY,EAAE,iBAAiB,CAAC,MAAM,CAAC,KACpC,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C,0BAA0B;IAC1B,YAAY,EAAE,MAAM,IAAI,CAAC;IAEzB,wBAAwB;IACxB,UAAU,EAAE,MAAM,IAAI,CAAC;IAEvB,4BAA4B;IAC5B,eAAe,EAAE,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CAChF"}
@@ -0,0 +1,30 @@
1
+ import type { UseFormInput, UseFormReturnType } from './types';
2
+ /**
3
+ * Form state management hook for React Native
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * const form = useForm({
8
+ * initialValues: {
9
+ * email: '',
10
+ * password: '',
11
+ * },
12
+ * validate: {
13
+ * email: isEmail('Invalid email'),
14
+ * password: minLength(6, 'Password must be at least 6 characters'),
15
+ * },
16
+ * });
17
+ *
18
+ * return (
19
+ * <View>
20
+ * <TextInput {...form.getInputProps('email')} />
21
+ * <TextInput {...form.getInputProps('password')} />
22
+ * <Button onPress={form.onSubmit((values) => console.log(values))}>
23
+ * Submit
24
+ * </Button>
25
+ * </View>
26
+ * );
27
+ * ```
28
+ */
29
+ export declare function useForm<Values extends Record<string, any> = Record<string, any>>({ initialValues, initialErrors, initialTouched, initialDirty, validate: validationRules, clearInputErrorOnChange, validateInputOnChange, validateInputOnBlur, transformValues, }?: UseFormInput<Values>): UseFormReturnType<Values>;
30
+ //# sourceMappingURL=useForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useForm.d.ts","sourceRoot":"","sources":["../../../../../../src/hooks/use-form/useForm.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAQV,YAAY,EACZ,iBAAiB,EAClB,MAAM,SAAS,CAAC;AA4DjB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,OAAO,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAChF,aAA4B,EAC5B,aAAkB,EAClB,cAAmB,EACnB,YAAiB,EACjB,QAAQ,EAAE,eAAe,EACzB,uBAA8B,EAC9B,qBAA6B,EAC7B,mBAA2B,EAC3B,eAA4C,GAC7C,GAAE,YAAY,CAAC,MAAM,CAAM,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAuUvD"}
@@ -0,0 +1,41 @@
1
+ import type { FormValidator } from './types';
2
+ /**
3
+ * Built-in validators
4
+ */
5
+ /**
6
+ * Validates that a value is not empty
7
+ */
8
+ export declare const isNotEmpty: (message?: string) => FormValidator<any>;
9
+ /**
10
+ * Validates minimum length
11
+ */
12
+ export declare const minLength: (min: number, message?: string) => FormValidator<string>;
13
+ /**
14
+ * Validates maximum length
15
+ */
16
+ export declare const maxLength: (max: number, message?: string) => FormValidator<string>;
17
+ /**
18
+ * Validates that value matches a pattern
19
+ */
20
+ export declare const matches: (pattern: RegExp, message?: string) => FormValidator<string>;
21
+ /**
22
+ * Validates email format
23
+ */
24
+ export declare const isEmail: (message?: string) => FormValidator<string>;
25
+ /**
26
+ * Validates minimum value
27
+ */
28
+ export declare const min: (minValue: number, message?: string) => FormValidator<number>;
29
+ /**
30
+ * Validates maximum value
31
+ */
32
+ export declare const max: (maxValue: number, message?: string) => FormValidator<number>;
33
+ /**
34
+ * Validates that value is in a range
35
+ */
36
+ export declare const inRange: (minValue: number, maxValue: number, message?: string) => FormValidator<number>;
37
+ /**
38
+ * Validates that value is in a list
39
+ */
40
+ export declare const isInArray: <T>(array: T[], message?: string) => FormValidator<T>;
41
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../../../../../src/hooks/use-form/validators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;GAEG;AAEH;;GAEG;AACH,eAAO,MAAM,UAAU,GAAI,gBAAkC,KAAG,aAAa,CAAC,GAAG,CAahF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,GACpB,KAAK,MAAM,EACX,UAAU,MAAM,KACf,aAAa,CAAC,MAAM,CAQtB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,GACpB,KAAK,MAAM,EACX,UAAU,MAAM,KACf,aAAa,CAAC,MAAM,CAQtB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAClB,SAAS,MAAM,EACf,gBAA0B,KACzB,aAAa,CAAC,MAAM,CAQtB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAAI,gBAAyB,KAAG,aAAa,CAAC,MAAM,CAGvE,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,GAAG,GACd,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,aAAa,CAAC,MAAM,CAQtB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,GAAG,GACd,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,aAAa,CAAC,MAAM,CAQtB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAClB,UAAU,MAAM,EAChB,UAAU,MAAM,EAChB,UAAU,MAAM,KACf,aAAa,CAAC,MAAM,CAQtB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,EACzB,OAAO,CAAC,EAAE,EACV,gBAAyB,KACxB,aAAa,CAAC,CAAC,CAOjB,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export * from './theme';
2
2
  export * from './components';
3
+ export * from './hooks';
3
4
  export type * from './theme/theme';
4
5
  export type * from './theme/types';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,mBAAmB,eAAe,CAAC;AACnC,mBAAmB,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,mBAAmB,eAAe,CAAC;AACnC,mBAAmB,eAAe,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mantine",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Make Mantine Accessable on React Native",
5
5
  "source": "./src/index.tsx",
6
6
  "main": "./lib/commonjs/index.js",
@@ -1,4 +1,5 @@
1
1
  import type { ViewStyle } from 'react-native';
2
+ import type React from 'react';
2
3
 
3
4
  import { BoxView } from '../BoxView';
4
5
  import type { ViewProps } from '../BoxView';
@@ -1,5 +1,5 @@
1
- import React, { forwardRef, useEffect, useRef } from 'react';
2
- import { Pressable, Animated } from 'react-native';
1
+ import React, { forwardRef, useEffect, useRef, createContext, useContext } from 'react';
2
+ import { Pressable, Animated, View } from 'react-native';
3
3
  import { BoxView } from '../BoxView';
4
4
  import { Text } from '../Text';
5
5
  import type { DefaultProps, MantineColor, MantineSize } from '../../theme/types';
@@ -36,6 +36,44 @@ export interface RadioProps extends DefaultProps {
36
36
  wrapperStyle?: any;
37
37
  }
38
38
 
39
+ export interface RadioGroupProps {
40
+ /** Current selected value */
41
+ value?: string;
42
+
43
+ /** Called when value changes */
44
+ onChange?: (value: string) => void;
45
+
46
+ /** Radio group children */
47
+ children: React.ReactNode;
48
+
49
+ /** Radio group name for accessibility */
50
+ name?: string;
51
+
52
+ /** Radio size for all children */
53
+ size?: MantineSize;
54
+
55
+ /** Radio color for all children */
56
+ color?: MantineColor;
57
+
58
+ /** Wrapper style */
59
+ style?: any;
60
+
61
+ /** Spacing between radio buttons */
62
+ spacing?: number;
63
+ }
64
+
65
+ interface RadioGroupContextValue {
66
+ value?: string;
67
+ onChange?: (value: string) => void;
68
+ size?: MantineSize;
69
+ color?: MantineColor;
70
+ name?: string;
71
+ }
72
+
73
+ const RadioGroupContext = createContext<RadioGroupContextValue | undefined>(undefined);
74
+
75
+ const useRadioGroupContext = () => useContext(RadioGroupContext);
76
+
39
77
  const sizes = {
40
78
  xs: rem(14),
41
79
  sm: rem(18),
@@ -103,20 +141,28 @@ const defaultProps: Partial<RadioProps> = {
103
141
  disabled: false,
104
142
  };
105
143
 
106
- export const Radio = forwardRef<any, RadioProps>((props, ref) => {
144
+ const RadioComponent = forwardRef<any, RadioProps>((props, ref) => {
145
+ const groupContext = useRadioGroupContext();
146
+
107
147
  const {
108
148
  label,
109
- size,
110
- color,
149
+ size: propSize,
150
+ color: propColor,
111
151
  value,
112
- checked,
113
- onChange,
152
+ checked: propChecked,
153
+ onChange: propOnChange,
114
154
  disabled,
115
155
  style,
116
156
  wrapperStyle,
117
157
  ...others
118
158
  } = useComponentDefaultProps('Radio', defaultProps, props);
119
159
 
160
+ // Use group context if available, otherwise use props
161
+ const size = propSize || groupContext?.size || defaultProps.size;
162
+ const color = propColor || groupContext?.color || defaultProps.color;
163
+ const checked = groupContext ? groupContext.value === value : propChecked;
164
+ const onChange = groupContext?.onChange || propOnChange;
165
+
120
166
  const { styles, sx } = useStyles({ size, color, disabled }, { name: 'Radio' }) as any;
121
167
 
122
168
  const scaleAnim = useRef(new Animated.Value(checked ? 1 : 0)).current;
@@ -158,6 +204,7 @@ export const Radio = forwardRef<any, RadioProps>((props, ref) => {
158
204
  style={sx(styles.root, wrapperStyle)}
159
205
  accessibilityRole="radio"
160
206
  accessibilityState={{ checked }}
207
+ hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}
161
208
  {...others}
162
209
  >
163
210
  {radioContent}
@@ -166,4 +213,48 @@ export const Radio = forwardRef<any, RadioProps>((props, ref) => {
166
213
  );
167
214
  });
168
215
 
169
- Radio.displayName = 'Radio';
216
+ RadioComponent.displayName = 'Radio';
217
+
218
+ const RadioGroup = forwardRef<View, RadioGroupProps>((props, ref) => {
219
+ const {
220
+ value,
221
+ onChange,
222
+ children,
223
+ name,
224
+ size,
225
+ color,
226
+ style,
227
+ spacing = 12,
228
+ } = props;
229
+
230
+ const contextValue: RadioGroupContextValue = {
231
+ value,
232
+ onChange,
233
+ size,
234
+ color,
235
+ name,
236
+ };
237
+
238
+ return (
239
+ <RadioGroupContext.Provider value={contextValue}>
240
+ <View ref={ref} style={style}>
241
+ {React.Children.map(children, (child, index) => {
242
+ if (!React.isValidElement(child)) {
243
+ return child;
244
+ }
245
+ return (
246
+ <View key={index} style={{ marginBottom: index < React.Children.count(children) - 1 ? spacing : 0 }}>
247
+ {child}
248
+ </View>
249
+ );
250
+ })}
251
+ </View>
252
+ </RadioGroupContext.Provider>
253
+ );
254
+ });
255
+
256
+ RadioGroup.displayName = 'RadioGroup';
257
+
258
+ export const Radio = Object.assign(RadioComponent, {
259
+ Group: RadioGroup,
260
+ });
@@ -19,15 +19,15 @@ export interface SwitchProps extends DefaultProps {
19
19
  /** Label position */
20
20
  labelPosition?: 'left' | 'right';
21
21
 
22
- /** Checked state */
22
+ /** Checked state (controlled component) */
23
23
  checked?: boolean;
24
24
 
25
- /** Default checked state */
26
- defaultChecked?: boolean;
27
-
28
25
  /** Called when switch state changes */
29
26
  onChange?: (value: boolean) => void;
30
27
 
28
+ /** Disabled state */
29
+ disabled?: boolean;
30
+
31
31
  /** Additional styles */
32
32
  style?: any;
33
33
 
@@ -78,7 +78,7 @@ const defaultProps: Partial<SwitchProps> = {
78
78
  size: 'md',
79
79
  color: 'blue',
80
80
  labelPosition: 'right',
81
- checked: false,
81
+ disabled: false,
82
82
  };
83
83
 
84
84
  export const Switch = forwardRef<any, SwitchProps>((props, ref) => {
@@ -89,6 +89,7 @@ export const Switch = forwardRef<any, SwitchProps>((props, ref) => {
89
89
  labelPosition,
90
90
  checked,
91
91
  onChange,
92
+ disabled,
92
93
  style,
93
94
  wrapperStyle,
94
95
  } = useComponentDefaultProps('Switch', defaultProps, props);
@@ -97,7 +98,9 @@ export const Switch = forwardRef<any, SwitchProps>((props, ref) => {
97
98
  const { styles, sx } = useStyles({ labelPosition, size }, { name: 'Switch' }) as any;
98
99
 
99
100
  const handleChange = (value: boolean) => {
100
- onChange?.(value);
101
+ if (!disabled) {
102
+ onChange?.(value);
103
+ }
101
104
  };
102
105
 
103
106
  const colorKey = color || theme.primaryColor;
@@ -126,6 +129,7 @@ export const Switch = forwardRef<any, SwitchProps>((props, ref) => {
126
129
  trackColor={trackColor}
127
130
  thumbColor={thumbColor}
128
131
  ios_backgroundColor={trackColor.false}
132
+ disabled={disabled}
129
133
  style={sx(styles.switch, style)}
130
134
  />
131
135
  );
@@ -0,0 +1,2 @@
1
+ export * from './useCachedResources';
2
+ export * from './use-form';
@@ -0,0 +1,3 @@
1
+ export { useForm } from './useForm';
2
+ export * from './types';
3
+ export * from './validators';
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Form field validation function
3
+ */
4
+ export type FormValidator<T> = (value: T) => string | null;
5
+
6
+ /**
7
+ * Form validation rules
8
+ */
9
+ export type FormValidationRules<Values> = {
10
+ [K in keyof Values]?: FormValidator<Values[K]> | FormValidator<Values[K]>[];
11
+ };
12
+
13
+ /**
14
+ * Form errors
15
+ */
16
+ export type FormErrors<Values = Record<string, any>> = Partial<
17
+ Record<keyof Values, string>
18
+ >;
19
+
20
+ /**
21
+ * Form touched state
22
+ */
23
+ export type FormTouched<Values = Record<string, any>> = Partial<
24
+ Record<keyof Values, boolean>
25
+ >;
26
+
27
+ /**
28
+ * Form dirty state
29
+ */
30
+ export type FormDirty<Values = Record<string, any>> = Partial<
31
+ Record<keyof Values, boolean>
32
+ >;
33
+
34
+ /**
35
+ * Form field status
36
+ */
37
+ export interface FormFieldStatus {
38
+ hasError: boolean;
39
+ isTouched: boolean;
40
+ isDirty: boolean;
41
+ }
42
+
43
+ /**
44
+ * Props to be spread on input components
45
+ */
46
+ export interface FormInputProps<T = any> {
47
+ value: T;
48
+ onChange?: (value: T) => void;
49
+ onChangeText?: (text: string) => void;
50
+ error?: string;
51
+ onBlur?: () => void;
52
+ }
53
+
54
+ /**
55
+ * Form submit handler
56
+ */
57
+ export type FormSubmitHandler<Values> = (
58
+ values: Values,
59
+ event?: any
60
+ ) => void | Promise<void>;
61
+
62
+ /**
63
+ * useForm hook input parameters
64
+ */
65
+ export interface UseFormInput<Values = Record<string, any>> {
66
+ /** Initial form values */
67
+ initialValues?: Values;
68
+
69
+ /** Initial form errors */
70
+ initialErrors?: FormErrors<Values>;
71
+
72
+ /** Initial touched state */
73
+ initialTouched?: FormTouched<Values>;
74
+
75
+ /** Initial dirty state */
76
+ initialDirty?: FormDirty<Values>;
77
+
78
+ /** Form validation rules */
79
+ validate?: FormValidationRules<Values>;
80
+
81
+ /** Clear input error on change */
82
+ clearInputErrorOnChange?: boolean;
83
+
84
+ /** Validate input on change */
85
+ validateInputOnChange?: boolean;
86
+
87
+ /** Validate input on blur */
88
+ validateInputOnBlur?: boolean;
89
+
90
+ /** Transform values before submit */
91
+ transformValues?: (values: Values) => any;
92
+ }
93
+
94
+ /**
95
+ * useForm hook return type
96
+ */
97
+ export interface UseFormReturnType<Values = Record<string, any>> {
98
+ /** Current form values */
99
+ values: Values;
100
+
101
+ /** Current form errors */
102
+ errors: FormErrors<Values>;
103
+
104
+ /** Current touched state */
105
+ touched: FormTouched<Values>;
106
+
107
+ /** Current dirty state */
108
+ dirty: FormDirty<Values>;
109
+
110
+ /** Set a single field value */
111
+ setFieldValue: <K extends keyof Values>(field: K, value: Values[K]) => void;
112
+
113
+ /** Set multiple values */
114
+ setValues: (values: Partial<Values>) => void;
115
+
116
+ /** Set a single field error */
117
+ setFieldError: <K extends keyof Values>(field: K, error: string | null) => void;
118
+
119
+ /** Set multiple errors */
120
+ setErrors: (errors: FormErrors<Values>) => void;
121
+
122
+ /** Clear a specific field error */
123
+ clearFieldError: <K extends keyof Values>(field: K) => void;
124
+
125
+ /** Clear all errors */
126
+ clearErrors: () => void;
127
+
128
+ /** Reset form to initial values */
129
+ reset: () => void;
130
+
131
+ /** Validate a specific field */
132
+ validateField: <K extends keyof Values>(field: K) => boolean;
133
+
134
+ /** Validate entire form */
135
+ validate: () => boolean;
136
+
137
+ /** Check if form is valid */
138
+ isValid: () => boolean;
139
+
140
+ /** Check if form is dirty */
141
+ isDirty: () => boolean;
142
+
143
+ /** Get field status */
144
+ getFieldStatus: <K extends keyof Values>(field: K) => FormFieldStatus;
145
+
146
+ /** Get props to spread on input component */
147
+ getInputProps: <K extends keyof Values>(
148
+ field: K,
149
+ options?: {
150
+ type?: 'input' | 'checkbox' | 'radio' | 'select';
151
+ withError?: boolean;
152
+ withFocus?: boolean;
153
+ }
154
+ ) => FormInputProps<Values[K]>;
155
+
156
+ /** Handle form submit */
157
+ onSubmit: (
158
+ handleSubmit: FormSubmitHandler<Values>
159
+ ) => (event?: any) => void | Promise<void>;
160
+
161
+ /** Reset touched state */
162
+ resetTouched: () => void;
163
+
164
+ /** Reset dirty state */
165
+ resetDirty: () => void;
166
+
167
+ /** Mark field as touched */
168
+ setFieldTouched: <K extends keyof Values>(field: K, touched?: boolean) => void;
169
+ }