react-native-better-html 1.0.11 → 1.0.12
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.
- package/dist/index.d.mts +91 -58
- package/dist/index.d.ts +91 -58
- package/dist/index.js +243 -102
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +251 -112
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -52,6 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
formatPhoneNumber: () => import_react_better_core11.formatPhoneNumber,
|
|
53
53
|
generateAsyncStorage: () => generateAsyncStorage,
|
|
54
54
|
generateRandomString: () => import_react_better_core11.generateRandomString,
|
|
55
|
+
getFormErrorObject: () => getFormErrorObject,
|
|
55
56
|
getPluralWord: () => import_react_better_core11.getPluralWord,
|
|
56
57
|
lightenColor: () => import_react_better_core11.lightenColor,
|
|
57
58
|
loaderControls: () => import_react_better_core11.loaderControls,
|
|
@@ -61,6 +62,7 @@ __export(index_exports, {
|
|
|
61
62
|
useBooleanState: () => import_react_better_core11.useBooleanState,
|
|
62
63
|
useDebounceState: () => import_react_better_core11.useDebounceState,
|
|
63
64
|
useDevice: () => useDevice,
|
|
65
|
+
useForm: () => useForm,
|
|
64
66
|
useKeyboard: () => useKeyboard,
|
|
65
67
|
useLoader: () => import_react_better_core11.useLoader,
|
|
66
68
|
useLoaderControls: () => import_react_better_core11.useLoaderControls,
|
|
@@ -465,6 +467,128 @@ function useComponentPropsGrouper(props, prefix) {
|
|
|
465
467
|
};
|
|
466
468
|
}, [props, prefix]);
|
|
467
469
|
}
|
|
470
|
+
function useForm(options) {
|
|
471
|
+
const { defaultValues, requiredFields, additional, onSubmit, validate } = options;
|
|
472
|
+
const inputFieldRefs = (0, import_react2.useRef)(
|
|
473
|
+
{}
|
|
474
|
+
);
|
|
475
|
+
const [values, setValues] = (0, import_react2.useState)(defaultValues);
|
|
476
|
+
const [errors, setErrors] = (0, import_react2.useState)({});
|
|
477
|
+
const [isSubmitting, setIsSubmitting] = (0, import_react_better_core2.useBooleanState)();
|
|
478
|
+
const numberOfInputFields = Object.keys(defaultValues).length;
|
|
479
|
+
const setFieldValue = (0, import_react2.useCallback)(
|
|
480
|
+
(field, value) => {
|
|
481
|
+
setValues((oldValue) => ({
|
|
482
|
+
...oldValue,
|
|
483
|
+
[field]: value
|
|
484
|
+
}));
|
|
485
|
+
setErrors((oldValue) => ({
|
|
486
|
+
...oldValue,
|
|
487
|
+
[field]: void 0
|
|
488
|
+
}));
|
|
489
|
+
},
|
|
490
|
+
[]
|
|
491
|
+
);
|
|
492
|
+
const setFieldsValue = (0, import_react2.useCallback)((values2) => {
|
|
493
|
+
setValues((oldValue) => ({
|
|
494
|
+
...oldValue,
|
|
495
|
+
...values2
|
|
496
|
+
}));
|
|
497
|
+
setErrors((oldValue) => {
|
|
498
|
+
const newErrors = {};
|
|
499
|
+
for (const key in values2) newErrors[key] = void 0;
|
|
500
|
+
return newErrors;
|
|
501
|
+
});
|
|
502
|
+
}, []);
|
|
503
|
+
const focusField = (0, import_react2.useCallback)((field) => {
|
|
504
|
+
inputFieldRefs.current[field]?.focus();
|
|
505
|
+
}, []);
|
|
506
|
+
const validateForm = (0, import_react2.useCallback)(() => {
|
|
507
|
+
const validationErrors = validate?.(values) || {};
|
|
508
|
+
setErrors(validationErrors);
|
|
509
|
+
return validationErrors;
|
|
510
|
+
}, [validate, values]);
|
|
511
|
+
const onSubmitFunction = (0, import_react2.useCallback)(
|
|
512
|
+
async (event) => {
|
|
513
|
+
event?.preventDefault();
|
|
514
|
+
setIsSubmitting.setTrue();
|
|
515
|
+
try {
|
|
516
|
+
const validationErrors = validateForm();
|
|
517
|
+
if (Object.keys(validationErrors).length === 0) {
|
|
518
|
+
await onSubmit?.(values);
|
|
519
|
+
} else {
|
|
520
|
+
const firstErrorField = Object.keys(validationErrors)[0];
|
|
521
|
+
focusField(firstErrorField);
|
|
522
|
+
}
|
|
523
|
+
} finally {
|
|
524
|
+
setIsSubmitting.setFalse();
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
[values, validateForm, onSubmit, focusField]
|
|
528
|
+
);
|
|
529
|
+
const getInputFieldProps = (0, import_react2.useCallback)(
|
|
530
|
+
(field) => {
|
|
531
|
+
const thisInputFieldIndex = Object.keys(values).findIndex((key) => key === field);
|
|
532
|
+
const isLastInputField = thisInputFieldIndex === numberOfInputFields - 1;
|
|
533
|
+
return {
|
|
534
|
+
required: requiredFields?.includes(field),
|
|
535
|
+
value: values[field]?.toString() ?? "",
|
|
536
|
+
errorMessage: errors[field],
|
|
537
|
+
returnKeyLabel: isLastInputField ? additional?.lastInputFieldReturnKeyLabel ?? "done" : "next",
|
|
538
|
+
onPressEnter: () => {
|
|
539
|
+
if (isLastInputField) onSubmitFunction();
|
|
540
|
+
else inputFieldRefs.current[Object.keys(values)[thisInputFieldIndex + 1]]?.focus();
|
|
541
|
+
},
|
|
542
|
+
onChange: (value) => {
|
|
543
|
+
setFieldValue(field, value);
|
|
544
|
+
},
|
|
545
|
+
ref: (element) => {
|
|
546
|
+
if (!element) return;
|
|
547
|
+
inputFieldRefs.current[field] = element;
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
},
|
|
551
|
+
[values, setFieldValue, errors, requiredFields, additional, onSubmitFunction]
|
|
552
|
+
);
|
|
553
|
+
const reset = (0, import_react2.useCallback)(() => {
|
|
554
|
+
setValues(defaultValues);
|
|
555
|
+
setErrors({});
|
|
556
|
+
}, [defaultValues]);
|
|
557
|
+
const isDirty = (0, import_react2.useMemo)(
|
|
558
|
+
() => Object.keys(defaultValues).some((key) => defaultValues[key] !== values[key]),
|
|
559
|
+
[defaultValues, values]
|
|
560
|
+
);
|
|
561
|
+
const isValid = (0, import_react2.useMemo)(() => {
|
|
562
|
+
const validationErrors = validate?.(values) || {};
|
|
563
|
+
return Object.keys(validationErrors).length === 0;
|
|
564
|
+
}, [validate, values]);
|
|
565
|
+
const canSubmit = (0, import_react2.useMemo)(() => {
|
|
566
|
+
const requiredFieldsHaveValues = requiredFields?.every((field) => values[field] !== void 0 && values[field] !== "") ?? true;
|
|
567
|
+
return isValid && requiredFieldsHaveValues;
|
|
568
|
+
}, [isValid, requiredFields]);
|
|
569
|
+
return {
|
|
570
|
+
values,
|
|
571
|
+
errors,
|
|
572
|
+
isSubmitting,
|
|
573
|
+
setFieldValue,
|
|
574
|
+
setFieldsValue,
|
|
575
|
+
getInputFieldProps,
|
|
576
|
+
focusField,
|
|
577
|
+
inputFieldRefs: inputFieldRefs.current,
|
|
578
|
+
validate: validateForm,
|
|
579
|
+
onSubmit: onSubmitFunction,
|
|
580
|
+
reset,
|
|
581
|
+
requiredFields,
|
|
582
|
+
isDirty,
|
|
583
|
+
isValid,
|
|
584
|
+
canSubmit
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
// src/utils/functions.ts
|
|
589
|
+
var getFormErrorObject = (formValues) => {
|
|
590
|
+
return {};
|
|
591
|
+
};
|
|
468
592
|
|
|
469
593
|
// src/utils/asyncStorage.ts
|
|
470
594
|
var import_async_storage = __toESM(require("@react-native-async-storage/async-storage"));
|
|
@@ -1205,6 +1329,8 @@ var InputFieldComponent = (0, import_react10.forwardRef)(
|
|
|
1205
1329
|
fontWeight = 400,
|
|
1206
1330
|
lineHeight = 20,
|
|
1207
1331
|
textAlign,
|
|
1332
|
+
required,
|
|
1333
|
+
disabled,
|
|
1208
1334
|
paddingHorizontal,
|
|
1209
1335
|
paddingVertical,
|
|
1210
1336
|
onFocus,
|
|
@@ -1261,111 +1387,124 @@ var InputFieldComponent = (0, import_react10.forwardRef)(
|
|
|
1261
1387
|
[]
|
|
1262
1388
|
);
|
|
1263
1389
|
const prefixSuffixBackgroundColor = colorTheme === "light" ? (0, import_react_better_core9.darkenColor)(theme2.colors.backgroundContent, 0.03) : (0, import_react_better_core9.lightenColor)(theme2.colors.backgroundContent, 0.1);
|
|
1264
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1390
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1391
|
+
Animate_default.View,
|
|
1392
|
+
{
|
|
1393
|
+
flex: 1,
|
|
1394
|
+
gap: theme2.styles.gap / 3,
|
|
1395
|
+
initialOpacity: 1,
|
|
1396
|
+
animateOpacity: disabled ? 0.6 : 1,
|
|
1397
|
+
children: [
|
|
1398
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(View_default, { isRow: true, width: "100%", alignItems: "center", gap: 2, children: [
|
|
1399
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text_default, { fontSize: 14, color: theme2.colors.textSecondary, children: label }),
|
|
1400
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text_default, { color: theme2.colors.error, children: "*" })
|
|
1401
|
+
] }),
|
|
1402
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(View_default, { isRow: true, position: "relative", alignItems: "center", flex: 1, height: readyHeight, children: [
|
|
1403
|
+
prefix && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1404
|
+
View_default,
|
|
1405
|
+
{
|
|
1406
|
+
isRow: true,
|
|
1407
|
+
height: "100%",
|
|
1408
|
+
backgroundColor: prefixSuffixBackgroundColor,
|
|
1409
|
+
alignItems: "center",
|
|
1410
|
+
borderWidth,
|
|
1411
|
+
borderRightWidth: 0,
|
|
1412
|
+
borderTopLeftRadius: theme2.styles.borderRadius,
|
|
1413
|
+
borderBottomLeftRadius: theme2.styles.borderRadius,
|
|
1414
|
+
borderColor: theme2.colors.border,
|
|
1415
|
+
paddingHorizontal: readyPaddingHorizontal,
|
|
1416
|
+
children: typeof prefix === "string" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text_default, { fontWeight: 700, children: prefix }) : prefix
|
|
1417
|
+
}
|
|
1418
|
+
),
|
|
1419
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1420
|
+
Animate_default.View,
|
|
1421
|
+
{
|
|
1422
|
+
flex: 1,
|
|
1423
|
+
backgroundColor: theme2.colors.backgroundContent,
|
|
1424
|
+
borderTopLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
|
|
1425
|
+
borderBottomLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
|
|
1426
|
+
borderTopRightRadius: suffix ? 0 : theme2.styles.borderRadius,
|
|
1427
|
+
borderBottomRightRadius: suffix ? 0 : theme2.styles.borderRadius,
|
|
1428
|
+
borderWidth,
|
|
1429
|
+
initialBorderColor: theme2.colors.border,
|
|
1430
|
+
animateBorderColor: isFocused ? theme2.colors.primary : isError ? theme2.colors.error : theme2.colors.border,
|
|
1431
|
+
overflow: "hidden",
|
|
1432
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1433
|
+
import_react_native8.TextInput,
|
|
1434
|
+
{
|
|
1435
|
+
style: textInputStyle,
|
|
1436
|
+
value: internalValue,
|
|
1437
|
+
defaultValue,
|
|
1438
|
+
autoCapitalize,
|
|
1439
|
+
autoComplete,
|
|
1440
|
+
autoCorrect,
|
|
1441
|
+
autoFocus,
|
|
1442
|
+
placeholder,
|
|
1443
|
+
placeholderTextColor: theme2.colors.textSecondary + "80",
|
|
1444
|
+
enterKeyHint: returnKeyLabel,
|
|
1445
|
+
returnKeyType,
|
|
1446
|
+
onSubmitEditing: onPressEnter,
|
|
1447
|
+
readOnly: !editable || disabled,
|
|
1448
|
+
textAlign,
|
|
1449
|
+
editable: !disabled,
|
|
1450
|
+
keyboardAppearance,
|
|
1451
|
+
keyboardType,
|
|
1452
|
+
cursorColor: theme2.colors.primary,
|
|
1453
|
+
selectionColor: theme2.colors.primary,
|
|
1454
|
+
secureTextEntry,
|
|
1455
|
+
onFocus: onFocusElement,
|
|
1456
|
+
onBlur: onBlurElement,
|
|
1457
|
+
onChangeText,
|
|
1458
|
+
onPress,
|
|
1459
|
+
ref: textInputRef
|
|
1460
|
+
}
|
|
1461
|
+
)
|
|
1462
|
+
}
|
|
1463
|
+
),
|
|
1464
|
+
suffix && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1465
|
+
View_default,
|
|
1298
1466
|
{
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
onSubmitEditing: onPressEnter,
|
|
1311
|
-
readOnly: !editable,
|
|
1312
|
-
textAlign,
|
|
1313
|
-
keyboardAppearance,
|
|
1314
|
-
keyboardType,
|
|
1315
|
-
cursorColor: theme2.colors.primary,
|
|
1316
|
-
selectionColor: theme2.colors.primary,
|
|
1317
|
-
secureTextEntry,
|
|
1318
|
-
onFocus: onFocusElement,
|
|
1319
|
-
onBlur: onBlurElement,
|
|
1320
|
-
onChangeText,
|
|
1321
|
-
onPress,
|
|
1322
|
-
ref: textInputRef
|
|
1467
|
+
isRow: true,
|
|
1468
|
+
height: "100%",
|
|
1469
|
+
backgroundColor: prefixSuffixBackgroundColor,
|
|
1470
|
+
alignItems: "center",
|
|
1471
|
+
borderWidth,
|
|
1472
|
+
borderLeftWidth: 0,
|
|
1473
|
+
borderTopRightRadius: theme2.styles.borderRadius,
|
|
1474
|
+
borderBottomRightRadius: theme2.styles.borderRadius,
|
|
1475
|
+
borderColor: theme2.colors.border,
|
|
1476
|
+
paddingHorizontal: readyPaddingHorizontal,
|
|
1477
|
+
children: typeof suffix === "string" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text_default, { fontWeight: 700, children: suffix }) : suffix
|
|
1323
1478
|
}
|
|
1324
1479
|
)
|
|
1325
|
-
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
children: infoMessage
|
|
1354
|
-
}
|
|
1355
|
-
),
|
|
1356
|
-
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1357
|
-
Animate_default.Text,
|
|
1358
|
-
{
|
|
1359
|
-
fontSize: 14,
|
|
1360
|
-
color: theme2.colors.error,
|
|
1361
|
-
initialHeight: 0,
|
|
1362
|
-
initialOpacity: 0,
|
|
1363
|
-
animateHeight: 17,
|
|
1364
|
-
animateOpacity: 1,
|
|
1365
|
-
children: errorMessage
|
|
1366
|
-
}
|
|
1367
|
-
)
|
|
1368
|
-
] });
|
|
1480
|
+
] }),
|
|
1481
|
+
infoMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1482
|
+
Animate_default.Text,
|
|
1483
|
+
{
|
|
1484
|
+
fontSize: 14,
|
|
1485
|
+
color: theme2.colors.textSecondary,
|
|
1486
|
+
initialHeight: 0,
|
|
1487
|
+
initialOpacity: 0,
|
|
1488
|
+
animateHeight: 17,
|
|
1489
|
+
animateOpacity: 1,
|
|
1490
|
+
children: infoMessage
|
|
1491
|
+
}
|
|
1492
|
+
),
|
|
1493
|
+
errorMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1494
|
+
Animate_default.Text,
|
|
1495
|
+
{
|
|
1496
|
+
fontSize: 14,
|
|
1497
|
+
color: theme2.colors.error,
|
|
1498
|
+
initialHeight: 0,
|
|
1499
|
+
initialOpacity: 0,
|
|
1500
|
+
animateHeight: 17,
|
|
1501
|
+
animateOpacity: 1,
|
|
1502
|
+
children: errorMessage
|
|
1503
|
+
}
|
|
1504
|
+
)
|
|
1505
|
+
]
|
|
1506
|
+
}
|
|
1507
|
+
);
|
|
1369
1508
|
}
|
|
1370
1509
|
);
|
|
1371
1510
|
InputFieldComponent.email = (0, import_react10.forwardRef)(function Email(props, ref) {
|
|
@@ -1472,6 +1611,7 @@ var asyncStoragePlugin = (options) => ({
|
|
|
1472
1611
|
formatPhoneNumber,
|
|
1473
1612
|
generateAsyncStorage,
|
|
1474
1613
|
generateRandomString,
|
|
1614
|
+
getFormErrorObject,
|
|
1475
1615
|
getPluralWord,
|
|
1476
1616
|
lightenColor,
|
|
1477
1617
|
loaderControls,
|
|
@@ -1481,6 +1621,7 @@ var asyncStoragePlugin = (options) => ({
|
|
|
1481
1621
|
useBooleanState,
|
|
1482
1622
|
useDebounceState,
|
|
1483
1623
|
useDevice,
|
|
1624
|
+
useForm,
|
|
1484
1625
|
useKeyboard,
|
|
1485
1626
|
useLoader,
|
|
1486
1627
|
useLoaderControls,
|