aport-tools 4.4.3 → 4.4.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,24 +1,129 @@
1
- import React, { ReactNode } from 'react';
1
+ import React from 'react';
2
2
  interface FormContextProps {
3
+ /**
4
+ * Stores the current form values as an object.
5
+ * Each key is a form field name and each value is the current value of that field.
6
+ * Example:
7
+ * ```ts
8
+ * formValues = { name: "John", email: "john@example.com" };
9
+ * ```
10
+ */
3
11
  formValues: Record<string, any>;
12
+ /**
13
+ * A function to update a specific form field value.
14
+ * It takes the `name` of the form field and the new `value` to be set.
15
+ * Example usage:
16
+ * ```ts
17
+ * setFormValue('email', 'newemail@example.com');
18
+ * ```
19
+ */
4
20
  setFormValue: (name: string, value: any) => void;
21
+ /**
22
+ * Stores the current form errors as an object.
23
+ * Each key is a form field name and the value is an array of error messages for that field.
24
+ * Example:
25
+ * ```ts
26
+ * errors = { email: ['Email is required', 'Invalid email format'] };
27
+ * ```
28
+ */
5
29
  errors: Record<string, string[]>;
30
+ /**
31
+ * A function to update the errors for all form fields.
32
+ * It takes an object where each key is a form field name and the value is an array of error messages for that field.
33
+ * Example usage:
34
+ * ```ts
35
+ * setErrors({ email: ['Email is required', 'Invalid email format'] });
36
+ * ```
37
+ */
6
38
  setErrors: (errors: Record<string, string[]>) => void;
39
+ /**
40
+ * A function to trigger the form submission.
41
+ * It will invoke the `onSubmit` handler and handle form validation errors.
42
+ * Typically, this function would call `onSubmit` and handle errors by updating the `errors` state.
43
+ */
7
44
  handleSubmit: () => void;
45
+ handleFormSubmit: (formValues: Record<string, any>) => Promise<Record<string, string[]>>;
8
46
  }
9
47
  export declare const useFormContext: () => FormContextProps;
10
48
  interface StepperProps {
49
+ /**
50
+ * Labels for each step (optional). If provided, these labels will display below each step indicator.
51
+ * Example: ['Step 1', 'Step 2', 'Step 3']
52
+ */
11
53
  steps?: string[];
54
+ /**
55
+ * Current step index (e.g., 0 for step 1, 1 for step 2).
56
+ * Determines the active step and progress display.
57
+ */
58
+ currentStep: number;
59
+ /**
60
+ * Enables or disables the ability to click on a step to navigate to it.
61
+ * Default is `false`.
62
+ */
12
63
  presseable?: boolean;
64
+ /**
65
+ * Callback function that gets triggered when a step is clicked.
66
+ * Passes the index of the clicked step as an argument.
67
+ * Example: (stepIndex) => console.log(`Step ${stepIndex} clicked!`)
68
+ */
13
69
  onPress?: (stepIndex: number) => void;
14
- step: number;
70
+ /**
71
+ * Determines the shape of the step indicator.
72
+ * Options:
73
+ * - `'circular'` (default)
74
+ * - `'square'`
75
+ */
76
+ stepStyle?: "circular" | "square";
77
+ /**
78
+ * Total number of steps in the stepper.
79
+ * Must be greater than or equal to 1.
80
+ */
15
81
  totalSteps: number;
82
+ /**
83
+ * Type of content displayed inside the step indicator.
84
+ * Options:
85
+ * - `'number'` (default): Displays the step index (e.g., 1, 2, 3).
86
+ * - `'icon'`: Displays a custom icon (requires the `icon` prop).
87
+ * - `'empty'`: Displays no content inside the step indicator.
88
+ */
16
89
  stepType?: "number" | "icon" | "empty";
90
+ /**
91
+ * Custom icon(s) to display inside step indicators when `stepType` is set to `'icon'`.
92
+ * Accepts:
93
+ * - A single icon for all steps (ReactNode or string URI).
94
+ * - An array of icons (ReactNode[] or string[]), one for each step.
95
+ * Example: ['https://example.com/icon1.png', 'https://example.com/icon2.png']
96
+ */
17
97
  icon?: React.ReactNode | React.ReactNode[];
18
98
  }
19
99
  interface FormProps {
20
- children: ReactNode;
100
+ /**
101
+ * The children elements to render inside the form.
102
+ * Typically this will be form fields or custom form components.
103
+ * This prop is required and must be passed as ReactNode(s).
104
+ */
105
+ children: React.ReactNode;
106
+ /**
107
+ * The callback function to handle form submission.
108
+ * It receives the form values as an object (`values`) and must return a promise
109
+ * that resolves to an object containing errors for the form fields.
110
+ * Example:
111
+ * ```ts
112
+ * const onSubmit = async (values: Record<string, any>) => {
113
+ * // handle the submission and return errors if any
114
+ * return { fieldName: ['Error message'] };
115
+ * }
116
+ * ```
117
+ * The return value should be an object where the keys are form field names
118
+ * and the values are arrays of error messages for those fields.
119
+ */
21
120
  onSubmit: (values: Record<string, any>) => Promise<Record<string, string[]>>;
121
+ /**
122
+ * Optional stepper configuration for the form.
123
+ * If provided, it will integrate a stepper component to display form steps.
124
+ * This is an optional prop, so the form can be used without it.
125
+ * The `StepperProps` interface will define the expected props for the stepper.
126
+ */
22
127
  stepper?: StepperProps;
23
128
  }
24
129
  export declare const Form: React.FC<FormProps>;
@@ -1,12 +1,53 @@
1
1
  import React from "react";
2
2
  interface StepperProps {
3
+ /**
4
+ * Labels for each step (optional). If provided, these labels will display below each step indicator.
5
+ * Example: ['Step 1', 'Step 2', 'Step 3']
6
+ */
3
7
  steps?: string[];
8
+ /**
9
+ * Current step index (e.g., 0 for step 1, 1 for step 2).
10
+ * Determines the active step and progress display.
11
+ */
4
12
  currentStep: number;
13
+ /**
14
+ * Enables or disables the ability to click on a step to navigate to it.
15
+ * Default is `false`.
16
+ */
5
17
  presseable?: boolean;
18
+ /**
19
+ * Callback function that gets triggered when a step is clicked.
20
+ * Passes the index of the clicked step as an argument.
21
+ * Example: (stepIndex) => console.log(`Step ${stepIndex} clicked!`)
22
+ */
6
23
  onPress?: (stepIndex: number) => void;
24
+ /**
25
+ * Determines the shape of the step indicator.
26
+ * Options:
27
+ * - `'circular'` (default)
28
+ * - `'square'`
29
+ */
7
30
  stepStyle?: "circular" | "square";
31
+ /**
32
+ * Total number of steps in the stepper.
33
+ * Must be greater than or equal to 1.
34
+ */
8
35
  totalSteps: number;
36
+ /**
37
+ * Type of content displayed inside the step indicator.
38
+ * Options:
39
+ * - `'number'` (default): Displays the step index (e.g., 1, 2, 3).
40
+ * - `'icon'`: Displays a custom icon (requires the `icon` prop).
41
+ * - `'empty'`: Displays no content inside the step indicator.
42
+ */
9
43
  stepType?: "number" | "icon" | "empty";
44
+ /**
45
+ * Custom icon(s) to display inside step indicators when `stepType` is set to `'icon'`.
46
+ * Accepts:
47
+ * - A single icon for all steps (ReactNode or string URI).
48
+ * - An array of icons (ReactNode[] or string[]), one for each step.
49
+ * Example: ['https://example.com/icon1.png', 'https://example.com/icon2.png']
50
+ */
10
51
  icon?: React.ReactNode | React.ReactNode[];
11
52
  }
12
53
  declare const Stepper: React.FC<StepperProps>;
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! aport-tools v4.4.3 | ISC */
1
+ /*! aport-tools v4.4.5 | ISC */
2
2
  import React, { useContext, useState, createContext, useCallback, useMemo } from 'react';
3
3
  import { StyleSheet, Text as Text$1, Animated, View, TouchableOpacity, Image, TextInput, Modal, Pressable, FlatList, Keyboard, Platform, Alert, ActivityIndicator } from 'react-native';
4
4
  import { ThemeContext } from 'aport-themes';
@@ -175,7 +175,7 @@ var Stepper = function Stepper(_a) {
175
175
  currentStep = _a.currentStep,
176
176
  _b = _a.presseable,
177
177
  presseable = _b === void 0 ? false : _b,
178
- _onPress = _a.onPress,
178
+ onPress = _a.onPress,
179
179
  _c = _a.stepStyle,
180
180
  stepStyle = _c === void 0 ? "circular" : _c,
181
181
  totalSteps = _a.totalSteps,
@@ -185,6 +185,30 @@ var Stepper = function Stepper(_a) {
185
185
  var progressAnim = React.useRef(new Animated.Value(0)).current;
186
186
  var theme = useContext(ThemeContext).theme;
187
187
  var colors = theme.colors;
188
+ var _e = useFormContext(),
189
+ formValues = _e.formValues,
190
+ handleFormSubmit = _e.handleFormSubmit;
191
+ var handleStepPress = function handleStepPress(stepIndex) {
192
+ return __awaiter(void 0, void 0, void 0, function () {
193
+ var errors;
194
+ return __generator(this, function (_a) {
195
+ switch (_a.label) {
196
+ case 0:
197
+ if (!presseable || stepIndex === currentStep) return [2 /*return*/];
198
+ return [4 /*yield*/, handleFormSubmit(formValues)];
199
+ case 1:
200
+ errors = _a.sent();
201
+ if (Object.keys(errors).length > 0) {
202
+ console.log("Validation failed. Cannot proceed to step", stepIndex);
203
+ return [2 /*return*/]; // Prevent step change
204
+ }
205
+ // Proceed to change step
206
+ onPress === null || onPress === void 0 ? void 0 : onPress(stepIndex);
207
+ return [2 /*return*/];
208
+ }
209
+ });
210
+ });
211
+ };
188
212
  React.useEffect(function () {
189
213
  Animated.timing(progressAnim, {
190
214
  toValue: currentStep,
@@ -248,10 +272,13 @@ var Stepper = function Stepper(_a) {
248
272
  case "number":
249
273
  default:
250
274
  return /*#__PURE__*/React.createElement(Text, {
251
- style: {
252
- fontSize: 16,
253
- fontWeight: "bold"
254
- }
275
+ b: true,
276
+ typeFont: "primary",
277
+ style: [currentStep >= index ? {
278
+ color: colors.textButton.hex
279
+ } : {
280
+ color: colors.text.hex
281
+ }]
255
282
  }, index + 1);
256
283
  }
257
284
  };
@@ -268,13 +295,11 @@ var Stepper = function Stepper(_a) {
268
295
  }],
269
296
  disabled: !presseable,
270
297
  onPress: function onPress() {
271
- return _onPress && _onPress(index);
298
+ return handleStepPress(index);
272
299
  }
273
300
  }, /*#__PURE__*/React.createElement(View, {
274
- style: [styles$9.step, stepStyle === "square" && styles$9.squareStep, currentStep >= index && {
275
- backgroundColor: colors.primary.hex
276
- }, {
277
- backgroundColor: colors.body.hex
301
+ style: [styles$9.step, stepStyle === "square" && styles$9.squareStep, {
302
+ backgroundColor: currentStep >= index ? colors.primary.hex : colors.body.hex
278
303
  }]
279
304
  }, renderStepContent(index)), steps && /*#__PURE__*/React.createElement(Text, {
280
305
  style: styles$9.stepText
@@ -387,22 +412,39 @@ var Form = function Form(_a) {
387
412
  });
388
413
  });
389
414
  };
415
+ var handleFormSubmit = function handleFormSubmit(formValues) {
416
+ return __awaiter(void 0, void 0, void 0, function () {
417
+ var validationErrors;
418
+ return __generator(this, function (_a) {
419
+ switch (_a.label) {
420
+ case 0:
421
+ return [4 /*yield*/, onSubmit(formValues)];
422
+ case 1:
423
+ validationErrors = _a.sent();
424
+ setErrors(validationErrors);
425
+ return [2 /*return*/, validationErrors];
426
+ }
427
+ });
428
+ });
429
+ };
390
430
  return /*#__PURE__*/React.createElement(FormContext.Provider, {
391
431
  value: {
392
432
  formValues: formValues,
393
433
  setFormValue: setFormValue,
394
434
  errors: errors,
395
435
  setErrors: setErrors,
396
- handleSubmit: handleSubmit
436
+ handleSubmit: handleSubmit,
437
+ handleFormSubmit: handleFormSubmit
397
438
  }
398
439
  }, stepper && (/*#__PURE__*/React.createElement(Stepper, {
399
440
  steps: stepper.steps,
400
- currentStep: stepper.step,
441
+ currentStep: stepper.currentStep,
401
442
  presseable: stepper.presseable,
402
443
  onPress: stepper.onPress,
403
444
  totalSteps: stepper.totalSteps,
404
445
  stepType: stepper.stepType,
405
- icon: stepper.icon
446
+ icon: stepper.icon,
447
+ stepStyle: stepper.stepStyle
406
448
  })), children);
407
449
  };
408
450