aport-tools 4.5.0 → 4.6.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 (39) hide show
  1. package/package.json +17 -34
  2. package/src/cards/Card.tsx +129 -0
  3. package/src/cards/index.ts +1 -0
  4. package/src/components/Button.tsx +180 -0
  5. package/src/fonts/Text.tsx +137 -0
  6. package/{dist/fonts/index.d.ts → src/fonts/index.ts} +1 -0
  7. package/src/forms/ErrorList.tsx +47 -0
  8. package/src/forms/FORMDOC.md +87 -0
  9. package/{dist/forms/Form.d.ts → src/forms/Form.tsx} +2 -0
  10. package/src/forms/FormContext.tsx +248 -0
  11. package/src/forms/Input.tsx +174 -0
  12. package/src/forms/InputAttach.tsx +184 -0
  13. package/src/forms/InputCheck.tsx +169 -0
  14. package/src/forms/InputList.tsx +304 -0
  15. package/src/forms/Label.tsx +26 -0
  16. package/src/forms/Stepper.tsx +289 -0
  17. package/src/forms/TextArea.tsx +91 -0
  18. package/{dist/forms/index.d.ts → src/forms/index.ts} +4 -2
  19. package/src/index.ts +6 -0
  20. package/dist/cards/Card.d.ts +0 -57
  21. package/dist/cards/index.d.ts +0 -1
  22. package/dist/components/Button.d.ts +0 -52
  23. package/dist/defaults/reanimatedWrapper.d.ts +0 -2
  24. package/dist/fonts/Text.d.ts +0 -64
  25. package/dist/forms/ErrorList.d.ts +0 -6
  26. package/dist/forms/FormContext.d.ts +0 -132
  27. package/dist/forms/Input.d.ts +0 -43
  28. package/dist/forms/InputAttach.d.ts +0 -16
  29. package/dist/forms/InputCheck.d.ts +0 -19
  30. package/dist/forms/InputList.d.ts +0 -93
  31. package/dist/forms/Label.d.ts +0 -7
  32. package/dist/forms/Stepper.d.ts +0 -54
  33. package/dist/forms/TextArea.d.ts +0 -13
  34. package/dist/index.d.ts +0 -4
  35. package/dist/index.esm.js +0 -1493
  36. package/dist/index.esm.js.map +0 -1
  37. package/dist/index.js +0 -1526
  38. package/dist/index.js.map +0 -1
  39. /package/{dist/buttons/index.d.ts → src/buttons/index.ts} +0 -0
package/dist/index.js DELETED
@@ -1,1526 +0,0 @@
1
- /*! aport-tools v4.5.0 | ISC */
2
- 'use strict';
3
-
4
- var React = require('react');
5
- var reactNative = require('react-native');
6
- var aportThemes = require('aport-themes');
7
- var ImagePicker = require('expo-image-picker');
8
-
9
- function _interopNamespaceDefault(e) {
10
- var n = Object.create(null);
11
- if (e) {
12
- Object.keys(e).forEach(function (k) {
13
- if (k !== 'default') {
14
- var d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: function () { return e[k]; }
18
- });
19
- }
20
- });
21
- }
22
- n.default = e;
23
- return Object.freeze(n);
24
- }
25
-
26
- var ImagePicker__namespace = /*#__PURE__*/_interopNamespaceDefault(ImagePicker);
27
-
28
- /******************************************************************************
29
- Copyright (c) Microsoft Corporation.
30
-
31
- Permission to use, copy, modify, and/or distribute this software for any
32
- purpose with or without fee is hereby granted.
33
-
34
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
35
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
36
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
37
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
38
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
39
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
40
- PERFORMANCE OF THIS SOFTWARE.
41
- ***************************************************************************** */
42
- /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
43
-
44
-
45
- var __assign = function() {
46
- __assign = Object.assign || function __assign(t) {
47
- for (var s, i = 1, n = arguments.length; i < n; i++) {
48
- s = arguments[i];
49
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
50
- }
51
- return t;
52
- };
53
- return __assign.apply(this, arguments);
54
- };
55
-
56
- function __rest(s, e) {
57
- var t = {};
58
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
59
- t[p] = s[p];
60
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
61
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
62
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
63
- t[p[i]] = s[p[i]];
64
- }
65
- return t;
66
- }
67
-
68
- function __awaiter(thisArg, _arguments, P, generator) {
69
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
70
- return new (P || (P = Promise))(function (resolve, reject) {
71
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
72
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
73
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
74
- step((generator = generator.apply(thisArg, _arguments || [])).next());
75
- });
76
- }
77
-
78
- function __generator(thisArg, body) {
79
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
80
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
81
- function verb(n) { return function (v) { return step([n, v]); }; }
82
- function step(op) {
83
- if (f) throw new TypeError("Generator is already executing.");
84
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
85
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
86
- if (y = 0, t) op = [op[0] & 2, t.value];
87
- switch (op[0]) {
88
- case 0: case 1: t = op; break;
89
- case 4: _.label++; return { value: op[1], done: false };
90
- case 5: _.label++; y = op[1]; op = [0]; continue;
91
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
92
- default:
93
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
94
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
95
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
96
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
97
- if (t[2]) _.ops.pop();
98
- _.trys.pop(); continue;
99
- }
100
- op = body.call(thisArg, _);
101
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
102
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
103
- }
104
- }
105
-
106
- function __spreadArray(to, from, pack) {
107
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
108
- if (ar || !(i in from)) {
109
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
110
- ar[i] = from[i];
111
- }
112
- }
113
- return to.concat(ar || Array.prototype.slice.call(from));
114
- }
115
-
116
- typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
117
- var e = new Error(message);
118
- return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
119
- };
120
-
121
- // src/fonts/Text.tsx
122
- /**
123
- * A dynamic Text component that supports HTML-like formatting.
124
- * Integrates with the Theme system for consistent styling.
125
- *
126
- * @param children - The content to be displayed inside the Text component.
127
- * @param size - Size of the text. Defaults to 'medium'.
128
- * @param b - If true, applies bold styling.
129
- * @param i - If true, applies italic styling.
130
- * @param type - Type of Text component. Defaults to 'text'.
131
- * @param typeFont - Type of Font component. Defaults to 'body'.
132
- * @param u - If true, applies underline styling.
133
- * @param align - Paragraph alignment. Defaults to 'left'.
134
- * @param h - Header level. Accepts 0 (none), 1, 2, or 3. Defaults to 0.
135
- * @param style - Additional styles to apply.
136
- */
137
- var Text = function Text(_a) {
138
- var _b;
139
- var children = _a.children,
140
- _c = _a.size,
141
- size = _c === void 0 ? 14 : _c,
142
- _d = _a.b,
143
- b = _d === void 0 ? false : _d,
144
- _e = _a.i,
145
- i = _e === void 0 ? false : _e,
146
- _f = _a.u,
147
- u = _f === void 0 ? false : _f,
148
- _g = _a.align,
149
- align = _g === void 0 ? 'left' : _g,
150
- _h = _a.type,
151
- type = _h === void 0 ? 'text' : _h,
152
- _j = _a.typeFont,
153
- typeFont = _j === void 0 ? 'body' : _j,
154
- _k = _a.h,
155
- h = _k === void 0 ? 0 : _k,
156
- style = _a.style;
157
- var theme = React.useContext(aportThemes.ThemeContext).theme;
158
- var colors = theme.colors,
159
- fonts = theme.fonts;
160
- // Determine font family and size based on 'typeFont'
161
- var fontSettings = fonts[typeFont] || fonts.body;
162
- var fontFamily = fontSettings.fontFamily;
163
- var fontSize = fontSettings.fontSize || size;
164
- // Calculate header size based on 'h' prop
165
- if (h === 1) fontSize = 32;else if (h === 2) fontSize = 24;else if (h === 3) fontSize = 18;
166
- // Define font weight based on bold prop
167
- var fontWeight = b ? '700' : fontSettings.fontWeight || '400';
168
- // Define font style based on italic prop
169
- var fontStyle = i ? 'italic' : 'normal';
170
- // Define text decoration based on underline prop
171
- var textDecorationLine = u ? 'underline' : 'none';
172
- // Define text alignment
173
- var textAlign = align;
174
- // Map the 'type' prop to the correct color from the theme
175
- var textColor = ((_b = colors[type]) === null || _b === void 0 ? void 0 : _b.hex) || colors.text.hex;
176
- // Combine all styles
177
- var textStyles = {
178
- fontSize: fontSize,
179
- fontWeight: fontWeight,
180
- fontFamily: fontFamily,
181
- fontStyle: fontStyle,
182
- textDecorationLine: textDecorationLine,
183
- textAlign: textAlign,
184
- color: textColor
185
- };
186
- return /*#__PURE__*/React.createElement(reactNative.Text, {
187
- style: [textStyles, style]
188
- }, children);
189
- };
190
- reactNative.StyleSheet.create({
191
- // Define any default styles if needed
192
- });
193
-
194
- var Stepper = function Stepper(_a) {
195
- var steps = _a.steps,
196
- currentStep = _a.currentStep,
197
- _b = _a.presseable,
198
- presseable = _b === void 0 ? false : _b,
199
- onPress = _a.onPress,
200
- _c = _a.stepStyle,
201
- stepStyle = _c === void 0 ? "circular" : _c,
202
- totalSteps = _a.totalSteps,
203
- _d = _a.stepType,
204
- stepType = _d === void 0 ? "number" : _d,
205
- icon = _a.icon;
206
- var progressAnim = React.useRef(new reactNative.Animated.Value(0)).current;
207
- var theme = React.useContext(aportThemes.ThemeContext).theme;
208
- var colors = theme.colors;
209
- var _e = useFormContext(),
210
- formValues = _e.formValues,
211
- handleFormSubmit = _e.handleFormSubmit;
212
- var _f = React.useState(false),
213
- errorBack = _f[0],
214
- seterrorBack = _f[1];
215
- var handleStepPress = function handleStepPress(stepIndex) {
216
- return __awaiter(void 0, void 0, void 0, function () {
217
- var targetStep, errors;
218
- return __generator(this, function (_a) {
219
- switch (_a.label) {
220
- case 0:
221
- if (!presseable || stepIndex === currentStep) return [2 /*return*/];
222
- targetStep = stepIndex > currentStep ? currentStep + 1 : currentStep - 1;
223
- if (!(targetStep > currentStep)) return [3 /*break*/, 2];
224
- return [4 /*yield*/, handleFormSubmit(formValues)];
225
- case 1:
226
- errors = _a.sent();
227
- if (Object.keys(errors).length > 0) {
228
- console.log("Validation failed at step ".concat(currentStep, ". Cannot proceed to step ").concat(targetStep, "."));
229
- seterrorBack(true);
230
- return [2 /*return*/]; // Stop if current step has errors
231
- }
232
- _a.label = 2;
233
- case 2:
234
- // Update step
235
- seterrorBack(false);
236
- onPress === null || onPress === void 0 ? void 0 : onPress(targetStep);
237
- return [2 /*return*/];
238
- }
239
- });
240
- });
241
- };
242
- React.useEffect(function () {
243
- reactNative.Animated.timing(progressAnim, {
244
- toValue: currentStep,
245
- duration: 500,
246
- useNativeDriver: false
247
- }).start();
248
- }, [currentStep]);
249
- React.useEffect(function () {
250
- if (stepType === "icon") {
251
- if (!icon) {
252
- console.error("Stepper: `icon` is required when stepType is 'icon'.");
253
- } else if (Array.isArray(icon) && icon.length !== totalSteps) {
254
- console.error("Stepper: Number of icons (".concat(icon.length, ") must match totalSteps (").concat(totalSteps, ")."));
255
- }
256
- }
257
- }, [stepType, icon, totalSteps]);
258
- var getSeparatorWidth = function getSeparatorWidth(index) {
259
- if (currentStep > index && currentStep < index + 1) {
260
- // Return the fractional percentage for odd steps
261
- return "".concat(((currentStep - index) * 100).toFixed(0), "%");
262
- }
263
- return currentStep > index ? "100%" : "0%";
264
- };
265
- var renderStepContent = function renderStepContent(index) {
266
- switch (stepType) {
267
- case "icon":
268
- if (Array.isArray(icon)) {
269
- var stepIcon = icon[index];
270
- if (typeof stepIcon === "string") {
271
- return /*#__PURE__*/React.createElement(reactNative.Image, {
272
- source: {
273
- uri: stepIcon
274
- },
275
- style: {
276
- width: 24,
277
- height: 24
278
- },
279
- resizeMode: "contain"
280
- });
281
- } else {
282
- console.error("Invalid icon value for step ".concat(index, ". Expected a string URI."));
283
- return null;
284
- }
285
- }
286
- if (typeof icon === "string") {
287
- return /*#__PURE__*/React.createElement(reactNative.Image, {
288
- source: {
289
- uri: icon
290
- },
291
- style: {
292
- width: 24,
293
- height: 24
294
- },
295
- resizeMode: "contain"
296
- });
297
- }
298
- console.error("Icon prop must be a string or an array of strings.");
299
- return null;
300
- case "empty":
301
- return null;
302
- case "number":
303
- default:
304
- return /*#__PURE__*/React.createElement(Text, {
305
- b: true,
306
- typeFont: "primary",
307
- style: [currentStep >= index ? {
308
- color: colors.textButton.hex
309
- } : {
310
- color: colors.text.hex
311
- }]
312
- }, index + 1);
313
- }
314
- };
315
- return /*#__PURE__*/React.createElement(reactNative.View, {
316
- style: styles$9.container
317
- }, Array.from({
318
- length: totalSteps
319
- }, function (_, index) {
320
- return /*#__PURE__*/React.createElement(React.Fragment, {
321
- key: index
322
- }, /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
323
- style: [styles$9.stepContainer, presseable && {
324
- cursor: "pointer"
325
- }],
326
- disabled: !presseable,
327
- onPress: function onPress() {
328
- return handleStepPress(index);
329
- }
330
- }, /*#__PURE__*/React.createElement(reactNative.View, {
331
- style: [styles$9.step, stepStyle === "square" && styles$9.squareStep, {
332
- backgroundColor: currentStep >= index ? !errorBack ? colors.primary.hex : colors.error.hex : colors.body.hex
333
- }]
334
- }, renderStepContent(index)), steps && /*#__PURE__*/React.createElement(Text, {
335
- style: styles$9.stepText
336
- }, steps[index])), index < totalSteps - 1 && (/*#__PURE__*/React.createElement(reactNative.View, {
337
- style: styles$9.separatorContainer
338
- }, /*#__PURE__*/React.createElement(reactNative.View, {
339
- style: styles$9.separatorBackground
340
- }), /*#__PURE__*/React.createElement(reactNative.Animated.View, {
341
- style: [styles$9.separatorProgress, {
342
- width: getSeparatorWidth(index),
343
- backgroundColor: colors.primary.hex
344
- }]
345
- }))));
346
- }));
347
- };
348
- var styles$9 = reactNative.StyleSheet.create({
349
- container: {
350
- flexDirection: "row",
351
- alignItems: "center",
352
- justifyContent: "space-between",
353
- marginBottom: 16
354
- },
355
- stepContainer: {
356
- alignItems: "center",
357
- flex: 1
358
- },
359
- step: {
360
- width: 30,
361
- height: 30,
362
- borderRadius: 15,
363
- // Default to circular
364
- alignItems: "center",
365
- justifyContent: "center",
366
- marginBottom: 4
367
- },
368
- squareStep: {
369
- borderRadius: 5 // Square shape
370
- },
371
- stepLabel: {
372
- color: "#ffffff",
373
- fontWeight: "bold"
374
- },
375
- stepText: {
376
- fontSize: 12,
377
- textAlign: "center",
378
- marginTop: 4
379
- },
380
- separatorContainer: {
381
- flex: 1,
382
- height: 4,
383
- marginHorizontal: 8,
384
- position: "relative"
385
- },
386
- separatorBackground: {
387
- position: "absolute",
388
- width: "100%",
389
- height: "100%",
390
- backgroundColor: "#aaaaaa",
391
- borderRadius: 2
392
- },
393
- separatorProgress: {
394
- position: "absolute",
395
- height: "100%",
396
- borderRadius: 2
397
- }
398
- });
399
-
400
- // src/forms/FormContext.tsx
401
- // Utility to use `setFormValue` globally
402
- var setFormValueGlobal = function setFormValueGlobal(name, value, firstValue) {
403
- {
404
- console.warn("setFormValueGlobal was called before the Form was rendered.");
405
- }
406
- };
407
- var FormContext = /*#__PURE__*/React.createContext(undefined);
408
- var useFormContext = function useFormContext() {
409
- var context = React.useContext(FormContext);
410
- if (!context) {
411
- throw new Error("useFormContext must be used within a Form");
412
- }
413
- return context;
414
- };
415
- var Form = function Form(_a) {
416
- var children = _a.children,
417
- onSubmit = _a.onSubmit,
418
- stepper = _a.stepper;
419
- var _b = React.useState({}),
420
- formValues = _b[0],
421
- setFormValues = _b[1];
422
- var _c = React.useState({}),
423
- errors = _c[0],
424
- setErrors = _c[1];
425
- var _d = React.useState({}),
426
- firstValues = _d[0],
427
- setFirstValues = _d[1]; // Track firstValues
428
- var setFormValue = function setFormValue(name, value, firstValue) {
429
- // Update formValues with the latest value
430
- setFormValues(function (prev) {
431
- var _a;
432
- return __assign(__assign({}, prev), (_a = {}, _a[name] = value, _a));
433
- });
434
- // If firstValue exists and is not empty, set it in firstValues
435
- if (firstValue !== undefined && firstValue !== null && firstValue !== "") {
436
- setFirstValues(function (prev) {
437
- var _a;
438
- return __assign(__assign({}, prev), (_a = {}, _a[name] = firstValue, _a));
439
- });
440
- }
441
- };
442
- var handleSubmit = function handleSubmit() {
443
- return __awaiter(void 0, void 0, void 0, function () {
444
- var modifiedValues, validationErrors;
445
- return __generator(this, function (_a) {
446
- switch (_a.label) {
447
- case 0:
448
- modifiedValues = Object.keys(formValues).reduce(function (result, key) {
449
- var hasFirstValue = key in firstValues;
450
- var isModified = hasFirstValue && formValues[key] !== firstValues[key];
451
- var isNewValue = !hasFirstValue;
452
- // If the field was modified or is a new value, include it in the modified values
453
- if (isModified || isNewValue) {
454
- result[key] = formValues[key];
455
- } else {
456
- // If there were no changes, use the firstValue
457
- if (hasFirstValue && firstValues[key] !== undefined) {
458
- result[key] = firstValues[key];
459
- }
460
- }
461
- return result;
462
- }, {});
463
- return [4 /*yield*/, onSubmit(modifiedValues)];
464
- case 1:
465
- validationErrors = _a.sent();
466
- // Set the validation errors in state
467
- setErrors(validationErrors);
468
- // Prevent submission if there are any errors
469
- if (Object.keys(validationErrors).length > 0) {
470
- return [2 /*return*/]; // Prevent submission
471
- }
472
- return [2 /*return*/];
473
- }
474
- });
475
- });
476
- };
477
- var handleFormSubmit = function handleFormSubmit(formValues) {
478
- return __awaiter(void 0, void 0, void 0, function () {
479
- var validationErrors;
480
- return __generator(this, function (_a) {
481
- switch (_a.label) {
482
- case 0:
483
- return [4 /*yield*/, onSubmit(formValues)];
484
- case 1:
485
- validationErrors = _a.sent();
486
- setErrors(validationErrors);
487
- return [2 /*return*/, validationErrors];
488
- }
489
- });
490
- });
491
- };
492
- return /*#__PURE__*/React.createElement(FormContext.Provider, {
493
- value: {
494
- formValues: formValues,
495
- setFormValue: setFormValue,
496
- errors: errors,
497
- setErrors: setErrors,
498
- handleSubmit: handleSubmit,
499
- handleFormSubmit: handleFormSubmit
500
- }
501
- }, stepper && (/*#__PURE__*/React.createElement(Stepper, {
502
- steps: stepper.steps,
503
- currentStep: stepper.currentStep,
504
- presseable: stepper.presseable,
505
- onPress: stepper.onPress,
506
- totalSteps: stepper.totalSteps,
507
- stepType: stepper.stepType,
508
- icon: stepper.icon,
509
- stepStyle: stepper.stepStyle
510
- })), children);
511
- };
512
-
513
- // src/forms/ErrorList.tsx
514
- var ErrorList = function ErrorList(_a) {
515
- var errors = _a.errors;
516
- var theme = React.useContext(aportThemes.ThemeContext).theme;
517
- var colors = theme.colors;
518
- return /*#__PURE__*/React.createElement(reactNative.View, {
519
- style: styles$8.container
520
- }, errors.map(function (error, index) {
521
- return /*#__PURE__*/React.createElement(reactNative.View, {
522
- key: index,
523
- style: styles$8.errorItem
524
- }, /*#__PURE__*/React.createElement(Text, {
525
- style: [styles$8.bullet, {
526
- color: colors.error.hex
527
- }]
528
- }, "\u2022"), /*#__PURE__*/React.createElement(Text, {
529
- style: [styles$8.errorText, {
530
- color: colors.error.hex
531
- }]
532
- }, error));
533
- }));
534
- };
535
- var styles$8 = reactNative.StyleSheet.create({
536
- container: {
537
- marginTop: 4
538
- },
539
- errorItem: {
540
- flexDirection: 'row',
541
- alignItems: 'flex-start',
542
- marginBottom: 2
543
- },
544
- bullet: {
545
- marginRight: 4,
546
- fontSize: 12
547
- },
548
- errorText: {
549
- flex: 1,
550
- fontSize: 12
551
- }
552
- });
553
-
554
- // src/forms/Input.tsx
555
- /**
556
- * Input component that supports labels, error messages, and integrates with the Theme system.
557
- *
558
- * @param {InputProps} props - Props passed to the component.
559
- * @returns {JSX.Element} The rendered Input component.
560
- *
561
- * @example
562
- * <Input
563
- * name="email"
564
- * label="Email"
565
- * keyboardType="email-address"
566
- * inputType="id"
567
- * />
568
- */
569
- var Input = function Input(_a) {
570
- var name = _a.name,
571
- label = _a.label,
572
- inputType = _a.inputType,
573
- firstValue = _a.firstValue,
574
- _b = _a.editable,
575
- editable = _b === void 0 ? true : _b,
576
- style = _a.style,
577
- rest = __rest(_a, ["name", "label", "inputType", "firstValue", "editable", "style"]);
578
- var _c = useFormContext(),
579
- formValues = _c.formValues,
580
- setFormValue = _c.setFormValue,
581
- formErrors = _c.errors;
582
- var theme = React.useContext(aportThemes.ThemeContext).theme;
583
- var colors = theme.colors;
584
- var _d = React.useState(""),
585
- internalValue = _d[0],
586
- setInternalValue = _d[1];
587
- var isFirstRender = React.useRef(true); // Track the first render
588
- // Initialize the internal value when `firstValue` changes or on first render
589
- React.useEffect(function () {
590
- if (isFirstRender.current) {
591
- isFirstRender.current = false;
592
- if (firstValue !== undefined) {
593
- firstValue = firstValue.toString();
594
- setInternalValue(firstValue);
595
- setFormValue(name, firstValue, firstValue); // Pass firstValue here
596
- } else {
597
- setInternalValue(formValues[name] || "");
598
- }
599
- }
600
- }, [firstValue]);
601
- /**
602
- * Handles text changes in the input field, applying formatting based on the inputType.
603
- *
604
- * @param {string} text - The current text input by the user.
605
- */
606
- var handleChange = function handleChange(text) {
607
- var formattedText = text;
608
- // Apply different formatting based on inputType
609
- switch (inputType) {
610
- case "phone":
611
- // Remove all non-digit characters
612
- formattedText = text.replace(/\D/g, "");
613
- // Insert hyphens to format as xxx-xxx-xxxx
614
- if (formattedText.length > 3 && formattedText.length <= 6) {
615
- formattedText = "".concat(formattedText.slice(0, 3), "-").concat(formattedText.slice(3));
616
- } else if (formattedText.length > 6) {
617
- formattedText = "".concat(formattedText.slice(0, 3), "-").concat(formattedText.slice(3, 6), "-").concat(formattedText.slice(6, 10));
618
- }
619
- break;
620
- case "id":
621
- case "uppercase":
622
- // Convert all input to uppercase
623
- formattedText = text.toUpperCase();
624
- break;
625
- case "numeric":
626
- // Allow only numeric input
627
- formattedText = text.replace(/\D/g, "");
628
- break;
629
- }
630
- setInternalValue(formattedText);
631
- setFormValue(name, formattedText);
632
- };
633
- return /*#__PURE__*/React.createElement(reactNative.View, {
634
- style: styles$7.container
635
- }, /*#__PURE__*/React.createElement(Text, {
636
- style: [styles$7.label, {
637
- color: colors.text.hex
638
- }]
639
- }, label), /*#__PURE__*/React.createElement(reactNative.TextInput, __assign({
640
- style: [styles$7.input, {
641
- backgroundColor: colors.body.hex,
642
- borderColor: formErrors[name] ? colors.error.hex : "#CCC",
643
- color: colors.text.hex
644
- }, style],
645
- value: internalValue,
646
- onChangeText: handleChange,
647
- placeholder: label,
648
- editable: editable,
649
- placeholderTextColor: colors.placeHolder.hex
650
- }, rest)), formErrors[name] && formErrors[name].length > 0 && (/*#__PURE__*/React.createElement(ErrorList, {
651
- errors: formErrors[name]
652
- })));
653
- };
654
- var styles$7 = reactNative.StyleSheet.create({
655
- container: {
656
- marginBottom: 16
657
- },
658
- label: {
659
- marginBottom: 4,
660
- fontSize: 14
661
- },
662
- input: {
663
- height: 40,
664
- borderWidth: 1,
665
- borderRadius: 4,
666
- paddingHorizontal: 8
667
- }
668
- });
669
-
670
- // src/forms/TextArea.tsx
671
- var TextArea = function TextArea(_a) {
672
- var name = _a.name,
673
- label = _a.label;
674
- _a.errors;
675
- var firstValue = _a.firstValue,
676
- _b = _a.editable,
677
- editable = _b === void 0 ? true : _b,
678
- style = _a.style,
679
- rest = __rest(_a, ["name", "label", "errors", "firstValue", "editable", "style"]);
680
- var _c = useFormContext(),
681
- formValues = _c.formValues,
682
- setFormValue = _c.setFormValue,
683
- formErrors = _c.errors;
684
- var theme = React.useContext(aportThemes.ThemeContext).theme;
685
- var colors = theme.colors;
686
- var _d = React.useState(""),
687
- internalValue = _d[0],
688
- setInternalValue = _d[1];
689
- var isFirstRender = React.useRef(true); // Track the first render
690
- // Initialize the internal value when `firstValue` changes or on first render
691
- React.useEffect(function () {
692
- if (isFirstRender.current) {
693
- isFirstRender.current = false;
694
- if (firstValue !== undefined) {
695
- setInternalValue(firstValue);
696
- setFormValue(name, firstValue, firstValue); // Pass firstValue here
697
- } else {
698
- setInternalValue(formValues[name] || "");
699
- }
700
- }
701
- }, [firstValue]);
702
- var handleChange = function handleChange(text) {
703
- setInternalValue(text);
704
- setFormValue(name, text);
705
- };
706
- return /*#__PURE__*/React.createElement(reactNative.View, {
707
- style: styles$6.container
708
- }, /*#__PURE__*/React.createElement(Text, {
709
- style: [styles$6.label, {
710
- color: colors.text.hex
711
- }]
712
- }, label), /*#__PURE__*/React.createElement(reactNative.TextInput, __assign({
713
- style: [styles$6.textArea, style, {
714
- backgroundColor: colors.body.hex,
715
- color: colors.text.hex,
716
- borderColor: formErrors[name] ? colors.error.hex : "#CCC"
717
- }],
718
- value: internalValue,
719
- onChangeText: handleChange,
720
- placeholder: label,
721
- placeholderTextColor: colors.placeHolder.hex,
722
- multiline: true,
723
- editable: editable,
724
- numberOfLines: 4,
725
- textAlignVertical: "top"
726
- }, rest)), formErrors[name] && formErrors[name].length > 0 && (/*#__PURE__*/React.createElement(ErrorList, {
727
- errors: formErrors[name]
728
- })));
729
- };
730
- var styles$6 = reactNative.StyleSheet.create({
731
- container: {
732
- marginBottom: 16
733
- },
734
- label: {
735
- marginBottom: 4
736
- },
737
- textArea: {
738
- height: 100,
739
- borderWidth: 1,
740
- borderRadius: 4,
741
- paddingHorizontal: 8,
742
- paddingVertical: 8
743
- }
744
- });
745
-
746
- // src/forms/Label.tsx
747
- var Label = function Label(_a) {
748
- var text = _a.text,
749
- style = _a.style;
750
- var theme = React.useContext(aportThemes.ThemeContext).theme;
751
- var colors = theme.colors;
752
- return /*#__PURE__*/React.createElement(Text, {
753
- style: [styles$5.label, style, {
754
- color: colors.text.hex
755
- }]
756
- }, text);
757
- };
758
- var styles$5 = reactNative.StyleSheet.create({
759
- label: {
760
- marginBottom: 4,
761
- fontWeight: '500'
762
- }
763
- });
764
-
765
- /**
766
- * InputList component - A custom dropdown list component for React Native with multi-selection support,
767
- * customizable styling, sorting, and configurable close behavior on selection or scrolling.
768
- *
769
- * @param {string} placeholder - Placeholder text for the input.
770
- * @param {object} style - Custom styles for the component.
771
- * @param {Option[]} options - Array of options to display in the dropdown.
772
- * @param {boolean} multi - Enables multi-selection mode.
773
- * @param {boolean} disabled - Disables the dropdown input.
774
- * @param {keyof Option} sortBy - Key to sort options by (e.g., 'id').
775
- * @param {boolean} separator - If true, adds a separator line between options.
776
- * @param {boolean} closeOnScroll - Closes the dropdown if the user scrolls the list.
777
- * @param {boolean} closeOnSelect - Closes the dropdown on selection in single-select mode.
778
- * @param {number} maxSelection - Maximum number of items selectable in multi-select mode.
779
- */
780
- var InputList = function InputList(_a) {
781
- var name = _a.name,
782
- _b = _a.placeholder,
783
- placeholder = _b === void 0 ? "Choose value/s" : _b,
784
- style = _a.style,
785
- options = _a.options,
786
- _c = _a.multi,
787
- multi = _c === void 0 ? false : _c,
788
- _d = _a.disabled,
789
- disabled = _d === void 0 ? false : _d,
790
- sortBy = _a.sortBy,
791
- _e = _a.firstValue,
792
- firstValue = _e === void 0 ? [] : _e,
793
- _f = _a.separator,
794
- separator = _f === void 0 ? false : _f,
795
- _g = _a.closeOnScroll,
796
- closeOnScroll = _g === void 0 ? false : _g,
797
- _h = _a.closeOnSelect,
798
- closeOnSelect = _h === void 0 ? true : _h,
799
- maxSelection = _a.maxSelection,
800
- onChange = _a.onChange;
801
- var _j = useFormContext();
802
- _j.formValues;
803
- var setFormValue = _j.setFormValue,
804
- formErrors = _j.errors;
805
- var _k = React.useState(false),
806
- isDropdownVisible = _k[0],
807
- setIsDropdownVisible = _k[1];
808
- // Memoize sorted options for performance
809
- var sortedOptions = React.useMemo(function () {
810
- return sortBy ? __spreadArray([], options, true).sort(function (a, b) {
811
- return a[sortBy] > b[sortBy] ? 1 : -1;
812
- }) : options;
813
- }, [options, sortBy]);
814
- var theme = React.useContext(aportThemes.ThemeContext).theme;
815
- var colors = theme.colors;
816
- // Initialize selected options based on firstValue
817
- // Filter initial selections from options based on `firstValue`
818
- var initialSelections = React.useMemo(function () {
819
- return options.filter(function (opt) {
820
- return firstValue.includes(opt.value);
821
- });
822
- }, [options, firstValue]);
823
- // State for selected options
824
- var _l = React.useState(multi ? initialSelections : initialSelections[0] || null),
825
- selectedOptions = _l[0],
826
- setSelectedOptions = _l[1];
827
- // Update form value when firstValue changes
828
- React.useEffect(function () {
829
- if (!firstValue || firstValue.length === 0) return;
830
- var matchedSelections = options.filter(function (opt) {
831
- return firstValue.includes(opt.value);
832
- });
833
- if (multi) {
834
- setSelectedOptions(matchedSelections);
835
- setFormValue(name, matchedSelections, matchedSelections);
836
- } else {
837
- var singleValue = matchedSelections[0] || null;
838
- setSelectedOptions(singleValue);
839
- setFormValue(name, singleValue, singleValue);
840
- }
841
- }, [firstValue, multi]);
842
- // Handle option selection
843
- var handleSelectOption = function handleSelectOption(option) {
844
- var updatedSelections;
845
- if (multi) {
846
- var selectedArray = Array.isArray(selectedOptions) ? selectedOptions : [];
847
- var alreadySelected = selectedArray.some(function (opt) {
848
- return opt.id === option.id;
849
- });
850
- updatedSelections = alreadySelected ? selectedArray.filter(function (opt) {
851
- return opt.id !== option.id;
852
- }) : __spreadArray(__spreadArray([], selectedArray, true), [option], false);
853
- if (!alreadySelected && maxSelection && updatedSelections.length >= maxSelection) {
854
- setIsDropdownVisible(false);
855
- }
856
- setFormValue(name, updatedSelections);
857
- } else {
858
- updatedSelections = option;
859
- setFormValue(name, option);
860
- if (closeOnSelect) setIsDropdownVisible(false);
861
- }
862
- setSelectedOptions(updatedSelections);
863
- if (onChange) onChange(updatedSelections);
864
- };
865
- var isItemDisabled = function isItemDisabled(option) {
866
- if (!multi) return false; // Disable check only applies for multi-select
867
- // Ensure selectedOptions is treated as an array
868
- var selectedArray = Array.isArray(selectedOptions) ? selectedOptions : [];
869
- return maxSelection && selectedArray.length >= maxSelection && !selectedArray.some(function (opt) {
870
- return opt.id === option.id;
871
- });
872
- };
873
- var renderSelectedText = function renderSelectedText() {
874
- if (multi) {
875
- // Ensure selectedOptions is treated as an array
876
- var selectedArray = Array.isArray(selectedOptions) ? selectedOptions : [];
877
- return selectedArray.map(function (opt) {
878
- return opt.label;
879
- }).join(', ') || placeholder;
880
- }
881
- return (selectedOptions === null || selectedOptions === void 0 ? void 0 : selectedOptions.label) || placeholder;
882
- };
883
- var toggleDropdown = function toggleDropdown() {
884
- if (!disabled) {
885
- setIsDropdownVisible(!isDropdownVisible);
886
- if (!isDropdownVisible) reactNative.Keyboard.dismiss();
887
- }
888
- };
889
- var handleCloseDropdown = React.useCallback(function () {
890
- if (isDropdownVisible) setIsDropdownVisible(false);
891
- }, [isDropdownVisible]);
892
- /**
893
- * Renders selected options as a comma-separated string or the placeholder if none selected.
894
- * @returns {string} - The display text for selected options or placeholder.
895
- */
896
- // Conditionally render item as disabled if max selection reached and item is unselected
897
- return /*#__PURE__*/React.createElement(reactNative.View, {
898
- style: [styles$4.container, style]
899
- }, /*#__PURE__*/React.createElement(reactNative.Text, {
900
- style: {
901
- color: colors.text.hex,
902
- marginBottom: 4
903
- }
904
- }, name), /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
905
- style: [styles$4.inputContainer, {
906
- borderColor: formErrors[name] ? colors.error.hex : "#CCC"
907
- }],
908
- onPress: toggleDropdown,
909
- disabled: disabled
910
- }, /*#__PURE__*/React.createElement(reactNative.Text, {
911
- style: {
912
- color: colors.text.hex
913
- }
914
- }, renderSelectedText())), formErrors[name] && formErrors[name].length > 0 && (/*#__PURE__*/React.createElement(ErrorList, {
915
- errors: formErrors[name]
916
- })), /*#__PURE__*/React.createElement(reactNative.Modal, {
917
- visible: isDropdownVisible,
918
- transparent: true,
919
- animationType: "fade"
920
- }, /*#__PURE__*/React.createElement(reactNative.Pressable, {
921
- style: styles$4.overlay,
922
- onPress: handleCloseDropdown
923
- }), /*#__PURE__*/React.createElement(reactNative.View, {
924
- style: [styles$4.dropdownContainer, {
925
- backgroundColor: colors.body.hex
926
- }]
927
- }, /*#__PURE__*/React.createElement(reactNative.FlatList, {
928
- data: sortedOptions,
929
- keyExtractor: function keyExtractor(item) {
930
- return item.id.toString();
931
- },
932
- renderItem: function renderItem(_a) {
933
- var item = _a.item;
934
- var isSelected = multi ? Array.isArray(selectedOptions) && selectedOptions.some(function (opt) {
935
- return opt.id === item.id;
936
- }) : selectedOptions && 'id' in selectedOptions && selectedOptions.id === item.id;
937
- var isDisabled = isItemDisabled(item);
938
- return /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
939
- onPress: function onPress() {
940
- return handleSelectOption(item);
941
- },
942
- style: [styles$4.optionItem, isSelected ? {
943
- backgroundColor: colors.primary.hex
944
- } : {}, isDisabled ? {
945
- backgroundColor: colors.placeHolder.hex
946
- } : {}],
947
- disabled: !!isDisabled
948
- }, /*#__PURE__*/React.createElement(reactNative.Text, {
949
- style: [isSelected ? {
950
- color: colors.body.hex
951
- } : {
952
- color: colors.text.hex
953
- }, isDisabled ? styles$4.disabledText : {}]
954
- }, item.label));
955
- },
956
- ItemSeparatorComponent: function ItemSeparatorComponent() {
957
- return separator ? /*#__PURE__*/React.createElement(reactNative.View, {
958
- style: styles$4.separator
959
- }) : null;
960
- },
961
- scrollEnabled: !closeOnScroll
962
- }))));
963
- };
964
- var styles$4 = reactNative.StyleSheet.create({
965
- container: {
966
- marginVertical: 10
967
- },
968
- inputContainer: {
969
- padding: 12,
970
- borderWidth: 1,
971
- borderRadius: 5
972
- },
973
- dropdownContainer: {
974
- position: 'absolute',
975
- top: '30%',
976
- // Center the dropdown vertically
977
- alignSelf: 'center',
978
- width: '90%',
979
- backgroundColor: '#fff',
980
- borderRadius: 8,
981
- elevation: 5,
982
- paddingVertical: 10
983
- },
984
- optionItem: {
985
- padding: 12
986
- },
987
- disabledText: {
988
- color: '#999'
989
- },
990
- separator: {
991
- height: 1,
992
- backgroundColor: '#ddd',
993
- marginHorizontal: 8
994
- },
995
- overlay: {
996
- flex: 1,
997
- backgroundColor: 'rgba(0,0,0,0.3)'
998
- }
999
- });
1000
-
1001
- // src/cards/Card.tsx
1002
- /**
1003
- * Card component that adapts its styles based on the current theme.
1004
- * Supports dynamic styling, shadows, and press animations.
1005
- *
1006
- * @param children - The content to be displayed inside the Card.
1007
- * @param style - Additional styles to apply to the Card.
1008
- * @param onPress - Function to execute when the Card is pressed.
1009
- * @param pressable - Determines if the Card is pressable. Defaults to false.
1010
- * @param borderRadius - Border radius of the Card. Defaults to 12.
1011
- * @param elevation - Elevation for Android shadow. Overrides default.
1012
- * @param shadowProps - Custom shadow properties for iOS. Overrides defaults.
1013
- */
1014
- var Card = function Card(_a) {
1015
- var children = _a.children,
1016
- style = _a.style,
1017
- onPress = _a.onPress,
1018
- _b = _a.pressable,
1019
- pressable = _b === void 0 ? false : _b,
1020
- _c = _a.borderRadius,
1021
- borderRadius = _c === void 0 ? 12 : _c,
1022
- _d = _a.elevation,
1023
- elevation = _d === void 0 ? 4 : _d,
1024
- _e = _a.shadowProps,
1025
- shadowProps = _e === void 0 ? {} : _e;
1026
- var theme = React.useContext(aportThemes.ThemeContext).theme;
1027
- var colors = theme.colors;
1028
- // Animation state for pressable effect
1029
- // Default shadow styles (improved platform-specific handling)
1030
- var defaultShadow = reactNative.Platform.select({
1031
- ios: {
1032
- shadowColor: (shadowProps === null || shadowProps === void 0 ? void 0 : shadowProps.shadowColor) || colors.text.hex,
1033
- // Defaulting to theme text color
1034
- shadowOffset: (shadowProps === null || shadowProps === void 0 ? void 0 : shadowProps.shadowOffset) || {
1035
- width: 0,
1036
- height: 2
1037
- },
1038
- shadowOpacity: (shadowProps === null || shadowProps === void 0 ? void 0 : shadowProps.shadowOpacity) || 0.1,
1039
- shadowRadius: (shadowProps === null || shadowProps === void 0 ? void 0 : shadowProps.shadowRadius) || 4
1040
- },
1041
- android: {
1042
- elevation: elevation // Only applies to Android
1043
- }
1044
- });
1045
- var cardStyles = [styles$3.container, {
1046
- borderRadius: borderRadius,
1047
- backgroundColor: colors.background.hex
1048
- }, defaultShadow,
1049
- // Dynamic shadows based on platform
1050
- style // External styles
1051
- ];
1052
- return pressable ? (/*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
1053
- activeOpacity: 0.8,
1054
- onPress: onPress,
1055
- style: cardStyles
1056
- }, children)) : (/*#__PURE__*/React.createElement(reactNative.View, {
1057
- style: cardStyles
1058
- }, children));
1059
- };
1060
- var styles$3 = reactNative.StyleSheet.create({
1061
- container: {
1062
- padding: 16,
1063
- borderRadius: 12
1064
- // Shadows handled dynamically with platform logic
1065
- }
1066
- });
1067
-
1068
- var InputCheck = function InputCheck(_a) {
1069
- var name = _a.name,
1070
- options = _a.options,
1071
- _b = _a.multi,
1072
- multi = _b === void 0 ? false : _b,
1073
- max = _a.max,
1074
- _c = _a.rowAmount,
1075
- rowAmount = _c === void 0 ? 3 : _c,
1076
- firstValue = _a.firstValue,
1077
- _d = _a.iconPosition,
1078
- iconPosition = _d === void 0 ? "row" : _d,
1079
- _e = _a.disabled,
1080
- disabled = _e === void 0 ? false : _e;
1081
- var _f = useFormContext();
1082
- _f.formValues;
1083
- var setFormValue = _f.setFormValue,
1084
- formErrors = _f.errors;
1085
- var _g = React.useState([]),
1086
- selectedValues = _g[0],
1087
- setSelectedValues = _g[1];
1088
- var theme = React.useContext(aportThemes.ThemeContext).theme;
1089
- var colors = theme.colors;
1090
- var isFirstRender = React.useRef(true);
1091
- // Initialize selectedValues on first render if firstValue is provided
1092
- React.useEffect(function () {
1093
- if (isFirstRender.current && firstValue) {
1094
- var initialSelectedValues = options.filter(function (option) {
1095
- return firstValue.some(function (fv) {
1096
- return fv.value === option.value;
1097
- });
1098
- });
1099
- setSelectedValues(initialSelectedValues);
1100
- setFormValue(name, initialSelectedValues, initialSelectedValues); // Update form context
1101
- isFirstRender.current = false; // Prevent subsequent updates
1102
- }
1103
- }, [firstValue, name, options, setFormValue]);
1104
- var handleSelect = function handleSelect(id, value) {
1105
- if (disabled) return;
1106
- var updatedSelection;
1107
- if (multi) {
1108
- var alreadySelected = selectedValues.find(function (item) {
1109
- return item.id === id;
1110
- });
1111
- if (alreadySelected) {
1112
- updatedSelection = selectedValues.filter(function (item) {
1113
- return item.id !== id;
1114
- });
1115
- } else {
1116
- if (max && selectedValues.length >= max) return; // Prevent selection beyond max
1117
- updatedSelection = __spreadArray(__spreadArray([], selectedValues, true), [{
1118
- id: id,
1119
- value: value
1120
- }], false);
1121
- }
1122
- } else {
1123
- updatedSelection = [{
1124
- id: id,
1125
- value: value
1126
- }];
1127
- }
1128
- setSelectedValues(updatedSelection);
1129
- setFormValue(name, updatedSelection);
1130
- };
1131
- var renderItem = function renderItem(_a) {
1132
- var item = _a.item;
1133
- var isSelected = selectedValues.some(function (selected) {
1134
- return selected.id === item.id.toString();
1135
- });
1136
- return /*#__PURE__*/React.createElement(Card, {
1137
- pressable: true,
1138
- onPress: function onPress() {
1139
- return handleSelect(item.id.toString(), item.value);
1140
- },
1141
- style: [styles$2.card, isSelected && {
1142
- backgroundColor: colors.primary.hex
1143
- },
1144
- // Replace with colors.primary.hex if available
1145
- disabled && styles$2.cardDisabled]
1146
- }, item.icon && (/*#__PURE__*/React.createElement(reactNative.Image, {
1147
- source: {
1148
- uri: item.icon
1149
- },
1150
- style: [styles$2.icon, iconPosition === "column" && styles$2.iconColumn]
1151
- })), item.label && (/*#__PURE__*/React.createElement(Text, {
1152
- style: [styles$2.label, {
1153
- color: isSelected ? colors.textButton.hex : colors.text.hex
1154
- }]
1155
- }, item.label)));
1156
- };
1157
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Text, {
1158
- style: styles$2.title
1159
- }, name), /*#__PURE__*/React.createElement(reactNative.FlatList, {
1160
- data: options,
1161
- renderItem: renderItem,
1162
- keyExtractor: function keyExtractor(item) {
1163
- return item.id;
1164
- },
1165
- numColumns: rowAmount,
1166
- columnWrapperStyle: rowAmount > 1 ? styles$2.row : undefined,
1167
- scrollEnabled: false
1168
- }), formErrors[name] && formErrors[name].length > 0 && (/*#__PURE__*/React.createElement(ErrorList, {
1169
- errors: formErrors[name]
1170
- })));
1171
- };
1172
- var styles$2 = reactNative.StyleSheet.create({
1173
- card: {
1174
- flex: 1,
1175
- margin: 5,
1176
- padding: 10,
1177
- borderWidth: 1,
1178
- borderColor: "#ccc",
1179
- borderRadius: 8,
1180
- alignItems: "center",
1181
- justifyContent: "center"
1182
- },
1183
- title: {
1184
- marginBottom: 4,
1185
- fontSize: 14
1186
- },
1187
- cardDisabled: {
1188
- opacity: 0.5
1189
- },
1190
- icon: {
1191
- width: 40,
1192
- height: 40,
1193
- marginBottom: 5
1194
- },
1195
- iconColumn: {
1196
- marginBottom: 10
1197
- },
1198
- label: {
1199
- fontSize: 14,
1200
- textAlign: "center"
1201
- },
1202
- row: {
1203
- justifyContent: "space-between"
1204
- }
1205
- });
1206
-
1207
- // src/components/InputAttach.tsx
1208
- var InputAttach = function InputAttach(_a) {
1209
- var name = _a.name,
1210
- _b = _a.type,
1211
- type = _b === void 0 ? ["png", "jpg", "jpeg"] : _b,
1212
- _c = _a.amount,
1213
- amount = _c === void 0 ? 1 : _c,
1214
- _d = _a.disabled,
1215
- disabled = _d === void 0 ? false : _d,
1216
- _e = _a.placeholder,
1217
- placeholder = _e === void 0 ? "Upload an image" : _e,
1218
- _f = _a.firstValue,
1219
- firstValue = _f === void 0 ? [] : _f;
1220
- var _g = useFormContext(),
1221
- setFormValue = _g.setFormValue,
1222
- formErrors = _g.errors;
1223
- var _h = React.useState([]),
1224
- selectedFiles = _h[0],
1225
- setSelectedFiles = _h[1];
1226
- // Ref to track initialization
1227
- var isInitialized = React.useRef(false);
1228
- // Sync firstValue with selectedFiles when it changes
1229
- React.useEffect(function () {
1230
- if (!isInitialized.current) {
1231
- setSelectedFiles(firstValue);
1232
- setFormValue(name, firstValue, firstValue); // Pass firstValue here
1233
- isInitialized.current = true;
1234
- }
1235
- }, [firstValue, name, setFormValue]);
1236
- var theme = React.useContext(aportThemes.ThemeContext).theme;
1237
- var colors = theme.colors;
1238
- var pickImage = function pickImage() {
1239
- return __awaiter(void 0, void 0, void 0, function () {
1240
- var permissionResult, result, selectedAssets, newFiles, invalidFiles, updatedFiles;
1241
- return __generator(this, function (_a) {
1242
- switch (_a.label) {
1243
- case 0:
1244
- if (disabled) return [2 /*return*/];
1245
- return [4 /*yield*/, ImagePicker__namespace.requestMediaLibraryPermissionsAsync()];
1246
- case 1:
1247
- permissionResult = _a.sent();
1248
- if (!permissionResult.granted) {
1249
- reactNative.Alert.alert("Permission Required", "We need access to your photos to upload images.");
1250
- return [2 /*return*/];
1251
- }
1252
- return [4 /*yield*/, ImagePicker__namespace.launchImageLibraryAsync({
1253
- mediaTypes: ["images"],
1254
- // Updated usage
1255
- allowsEditing: true,
1256
- allowsMultipleSelection: amount > 1,
1257
- quality: 1
1258
- })];
1259
- case 2:
1260
- result = _a.sent();
1261
- if (!result.canceled) {
1262
- selectedAssets = result.assets || [result];
1263
- newFiles = selectedAssets.map(function (asset) {
1264
- return {
1265
- uri: asset.uri,
1266
- name: asset.fileName || "unknown.jpg",
1267
- type: asset.mimeType || "image/jpeg"
1268
- };
1269
- });
1270
- invalidFiles = newFiles.filter(function (file) {
1271
- return !type.some(function (ext) {
1272
- return file.name.toLowerCase().endsWith(ext);
1273
- });
1274
- });
1275
- if (invalidFiles.length > 0) {
1276
- reactNative.Alert.alert("Invalid File Type", "Please upload files of type: ".concat(type.join(", ")));
1277
- return [2 /*return*/];
1278
- }
1279
- // Check max amount
1280
- if (selectedFiles.length + newFiles.length > amount) {
1281
- reactNative.Alert.alert("Limit Exceeded", "You can upload up to ".concat(amount, " files."));
1282
- return [2 /*return*/];
1283
- }
1284
- updatedFiles = __spreadArray(__spreadArray([], selectedFiles, true), newFiles, true).slice(0, amount);
1285
- setSelectedFiles(updatedFiles);
1286
- setFormValue(name, updatedFiles); // Update form context
1287
- }
1288
- return [2 /*return*/];
1289
- }
1290
- });
1291
- });
1292
- };
1293
- var removeFile = function removeFile(index) {
1294
- var updatedFiles = selectedFiles.filter(function (_, i) {
1295
- return i !== index;
1296
- });
1297
- setSelectedFiles(updatedFiles);
1298
- setFormValue(name, updatedFiles); // Update form context
1299
- };
1300
- return /*#__PURE__*/React.createElement(reactNative.View, {
1301
- style: styles$1.container
1302
- }, /*#__PURE__*/React.createElement(Text, {
1303
- style: [styles$1.label, {
1304
- color: colors.text.hex
1305
- }]
1306
- }, placeholder), /*#__PURE__*/React.createElement(reactNative.View, {
1307
- style: styles$1.fileContainer
1308
- }, selectedFiles.map(function (file, index) {
1309
- return /*#__PURE__*/React.createElement(reactNative.View, {
1310
- key: index,
1311
- style: styles$1.fileItem
1312
- }, /*#__PURE__*/React.createElement(reactNative.Image, {
1313
- source: {
1314
- uri: file.uri
1315
- },
1316
- style: styles$1.imagePreview
1317
- }), /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
1318
- onPress: function onPress() {
1319
- return removeFile(index);
1320
- },
1321
- style: [styles$1.removeButton, {
1322
- backgroundColor: colors.error.hex
1323
- }]
1324
- }, /*#__PURE__*/React.createElement(Text, {
1325
- style: styles$1.removeButtonText
1326
- }, "X")));
1327
- }), selectedFiles.length < amount && (/*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
1328
- onPress: pickImage,
1329
- style: [styles$1.addButton, {
1330
- backgroundColor: colors.body.hex,
1331
- borderColor: formErrors[name] && colors.error.hex
1332
- }],
1333
- disabled: disabled
1334
- }, /*#__PURE__*/React.createElement(Text, {
1335
- style: [styles$1.addButtonText, {
1336
- color: colors.placeHolder.hex
1337
- }]
1338
- }, "+")))), formErrors[name] && formErrors[name].length > 0 && (/*#__PURE__*/React.createElement(ErrorList, {
1339
- errors: formErrors[name]
1340
- })));
1341
- };
1342
- var styles$1 = reactNative.StyleSheet.create({
1343
- container: {
1344
- marginVertical: 10
1345
- },
1346
- label: {
1347
- marginTop: 5
1348
- },
1349
- fileContainer: {
1350
- flexDirection: "row",
1351
- flexWrap: "wrap",
1352
- gap: 10
1353
- },
1354
- fileItem: {
1355
- position: "relative",
1356
- width: 100,
1357
- height: 100,
1358
- marginRight: 10
1359
- },
1360
- imagePreview: {
1361
- width: "100%",
1362
- height: "100%",
1363
- borderRadius: 5
1364
- },
1365
- removeButton: {
1366
- position: "absolute",
1367
- top: 0,
1368
- right: 0,
1369
- width: 20,
1370
- height: 20,
1371
- justifyContent: "center",
1372
- alignItems: "center",
1373
- borderRadius: 10
1374
- },
1375
- removeButtonText: {
1376
- color: "#fff",
1377
- fontWeight: "bold"
1378
- },
1379
- addButton: {
1380
- width: 100,
1381
- height: 100,
1382
- justifyContent: "center",
1383
- alignItems: "center",
1384
- borderRadius: 5
1385
- },
1386
- addButtonText: {
1387
- fontSize: 24
1388
- },
1389
- error: {
1390
- marginTop: 5
1391
- }
1392
- });
1393
-
1394
- // src/components/Button.tsx
1395
- /**
1396
- * Determines the styles based on the button type and whether it is disabled.
1397
- *
1398
- * @param type - The type of the button ('submit', 'button', 'cancel').
1399
- * @param disabled - Whether the button is disabled.
1400
- * @param themeColors - The theme colors.
1401
- * @returns The computed style for the button.
1402
- */
1403
- function typeStyles(type, disabled, themeColors) {
1404
- switch (type) {
1405
- case 'submit':
1406
- return {
1407
- backgroundColor: "rgba(".concat(themeColors === null || themeColors === void 0 ? void 0 : themeColors.primary.rgb.r, ", ").concat(themeColors === null || themeColors === void 0 ? void 0 : themeColors.primary.rgb.g, ", ").concat(themeColors === null || themeColors === void 0 ? void 0 : themeColors.primary.rgb.b, ", ").concat(disabled ? 0.5 : 1, ")"),
1408
- borderWidth: 2,
1409
- borderColor: themeColors === null || themeColors === void 0 ? void 0 : themeColors.primary.hex
1410
- };
1411
- case 'button':
1412
- return {
1413
- backgroundColor: themeColors === null || themeColors === void 0 ? void 0 : themeColors.primary.hex,
1414
- borderColor: themeColors === null || themeColors === void 0 ? void 0 : themeColors.secondary.hex,
1415
- opacity: disabled ? 0.5 : 1,
1416
- borderWidth: 2
1417
- };
1418
- case 'cancel':
1419
- return {
1420
- backgroundColor: themeColors === null || themeColors === void 0 ? void 0 : themeColors.background.hex,
1421
- borderWidth: 0
1422
- };
1423
- default:
1424
- return {};
1425
- }
1426
- }
1427
- /**
1428
- * Button component that adapts its styles based on the current theme.
1429
- * Supports dynamic styling, full-width option, rounded corners, and different types.
1430
- *
1431
- * @param disabled - If true, the button is disabled and not pressable.
1432
- * @param isFullWidth - If true, the button expands to full width of its container.
1433
- * @param children - Text content of the button.
1434
- * @param onPress - Function to call when the button is pressed.
1435
- * @param rounded - If true, the button has rounded corners.
1436
- * @param borderRadius - Custom border radius value. Overrides the `rounded` prop if provided.
1437
- * @param type - Specifies the button type for styling ('submit', 'button', 'cancel').
1438
- */
1439
- var Button = function Button(_a) {
1440
- var children = _a.children,
1441
- _b = _a.disabled,
1442
- disabled = _b === void 0 ? false : _b,
1443
- _c = _a.type,
1444
- type = _c === void 0 ? 'button' : _c,
1445
- _d = _a.rounded,
1446
- rounded = _d === void 0 ? true : _d,
1447
- _e = _a.borderRadius,
1448
- borderRadius = _e === void 0 ? 30 : _e,
1449
- _f = _a.isFullWidth,
1450
- isFullWidth = _f === void 0 ? false : _f,
1451
- _g = _a.loading,
1452
- loading = _g === void 0 ? false : _g,
1453
- onPress = _a.onPress;
1454
- var theme = React.useContext(aportThemes.ThemeContext).theme;
1455
- var colors = theme.colors;
1456
- var computedStyles = React.useMemo(function () {
1457
- return reactNative.StyleSheet.flatten([styles.button, typeStyles(type, disabled, colors), rounded && {
1458
- borderRadius: borderRadius
1459
- }, isFullWidth && {
1460
- width: '100%'
1461
- }, (disabled || loading) && styles.disabled]);
1462
- }, [type, disabled, loading, rounded, borderRadius, isFullWidth, colors]);
1463
- var textColor = React.useMemo(function () {
1464
- return type === "cancel" ? {
1465
- color: colors.text.hex
1466
- } : {
1467
- color: colors.textButton.hex
1468
- };
1469
- }, [type, colors]);
1470
- // Safely try to access handleSubmit from the form context
1471
- var formContext = function () {
1472
- try {
1473
- return useFormContext();
1474
- } catch (_a) {
1475
- return null;
1476
- }
1477
- }();
1478
- var handlePress = function handlePress() {
1479
- if (type === 'submit' && (formContext === null || formContext === void 0 ? void 0 : formContext.handleSubmit)) {
1480
- console.log("Its submit type");
1481
- formContext.handleSubmit();
1482
- } else if (onPress) {
1483
- onPress();
1484
- }
1485
- };
1486
- return /*#__PURE__*/React.createElement(reactNative.TouchableOpacity, {
1487
- style: computedStyles,
1488
- disabled: disabled || loading,
1489
- onPress: handlePress,
1490
- activeOpacity: 0.7
1491
- }, loading ? (
1492
- /*#__PURE__*/
1493
- // Show loading spinner if loading
1494
- React.createElement(reactNative.ActivityIndicator, {
1495
- size: "small",
1496
- color: colors.textButton.hex
1497
- })) : (/*#__PURE__*/React.createElement(reactNative.Text, {
1498
- style: textColor
1499
- }, Array.isArray(children) ? children.join('').toUpperCase() : children === null || children === void 0 ? void 0 : children.toUpperCase())));
1500
- };
1501
- var styles = reactNative.StyleSheet.create({
1502
- button: {
1503
- justifyContent: 'center',
1504
- alignItems: 'center',
1505
- paddingVertical: 10,
1506
- paddingHorizontal: 20
1507
- },
1508
- disabled: {
1509
- opacity: 0.6
1510
- }
1511
- });
1512
-
1513
- exports.Button = Button;
1514
- exports.Card = Card;
1515
- exports.ErrorList = ErrorList;
1516
- exports.Form = Form;
1517
- exports.Input = Input;
1518
- exports.InputAttach = InputAttach;
1519
- exports.InputCheck = InputCheck;
1520
- exports.InputList = InputList;
1521
- exports.Label = Label;
1522
- exports.Text = Text;
1523
- exports.TextArea = TextArea;
1524
- exports.setFormValueGlobal = setFormValueGlobal;
1525
- exports.useFormContext = useFormContext;
1526
- //# sourceMappingURL=index.js.map