react-native-better-html 1.0.10 → 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 +95 -52
- package/dist/index.d.ts +95 -52
- package/dist/index.js +254 -80
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +263 -91
- 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"));
|
|
@@ -1187,6 +1311,10 @@ var InputFieldComponent = (0, import_react10.forwardRef)(
|
|
|
1187
1311
|
defaultValue,
|
|
1188
1312
|
value,
|
|
1189
1313
|
editable = true,
|
|
1314
|
+
label,
|
|
1315
|
+
isError,
|
|
1316
|
+
infoMessage,
|
|
1317
|
+
errorMessage,
|
|
1190
1318
|
autoFocus,
|
|
1191
1319
|
autoCapitalize,
|
|
1192
1320
|
autoComplete,
|
|
@@ -1201,6 +1329,8 @@ var InputFieldComponent = (0, import_react10.forwardRef)(
|
|
|
1201
1329
|
fontWeight = 400,
|
|
1202
1330
|
lineHeight = 20,
|
|
1203
1331
|
textAlign,
|
|
1332
|
+
required,
|
|
1333
|
+
disabled,
|
|
1204
1334
|
paddingHorizontal,
|
|
1205
1335
|
paddingVertical,
|
|
1206
1336
|
onFocus,
|
|
@@ -1257,84 +1387,124 @@ var InputFieldComponent = (0, import_react10.forwardRef)(
|
|
|
1257
1387
|
[]
|
|
1258
1388
|
);
|
|
1259
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);
|
|
1260
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
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
|
-
|
|
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,
|
|
1466
|
+
{
|
|
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
|
|
1478
|
+
}
|
|
1479
|
+
)
|
|
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,
|
|
1292
1495
|
{
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
placeholder,
|
|
1301
|
-
placeholderTextColor: theme2.colors.textSecondary + "80",
|
|
1302
|
-
enterKeyHint: returnKeyLabel,
|
|
1303
|
-
returnKeyType,
|
|
1304
|
-
onSubmitEditing: onPressEnter,
|
|
1305
|
-
readOnly: !editable,
|
|
1306
|
-
textAlign,
|
|
1307
|
-
keyboardAppearance,
|
|
1308
|
-
keyboardType,
|
|
1309
|
-
cursorColor: theme2.colors.primary,
|
|
1310
|
-
selectionColor: theme2.colors.primary,
|
|
1311
|
-
secureTextEntry,
|
|
1312
|
-
onFocus: onFocusElement,
|
|
1313
|
-
onBlur: onBlurElement,
|
|
1314
|
-
onChangeText,
|
|
1315
|
-
onPress,
|
|
1316
|
-
ref: textInputRef
|
|
1496
|
+
fontSize: 14,
|
|
1497
|
+
color: theme2.colors.error,
|
|
1498
|
+
initialHeight: 0,
|
|
1499
|
+
initialOpacity: 0,
|
|
1500
|
+
animateHeight: 17,
|
|
1501
|
+
animateOpacity: 1,
|
|
1502
|
+
children: errorMessage
|
|
1317
1503
|
}
|
|
1318
1504
|
)
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
View_default,
|
|
1323
|
-
{
|
|
1324
|
-
isRow: true,
|
|
1325
|
-
height: "100%",
|
|
1326
|
-
backgroundColor: prefixSuffixBackgroundColor,
|
|
1327
|
-
alignItems: "center",
|
|
1328
|
-
borderWidth,
|
|
1329
|
-
borderLeftWidth: 0,
|
|
1330
|
-
borderTopRightRadius: theme2.styles.borderRadius,
|
|
1331
|
-
borderBottomRightRadius: theme2.styles.borderRadius,
|
|
1332
|
-
borderColor: theme2.colors.border,
|
|
1333
|
-
paddingHorizontal: readyPaddingHorizontal,
|
|
1334
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text_default, { fontWeight: 700, children: suffix })
|
|
1335
|
-
}
|
|
1336
|
-
)
|
|
1337
|
-
] });
|
|
1505
|
+
]
|
|
1506
|
+
}
|
|
1507
|
+
);
|
|
1338
1508
|
}
|
|
1339
1509
|
);
|
|
1340
1510
|
InputFieldComponent.email = (0, import_react10.forwardRef)(function Email(props, ref) {
|
|
@@ -1365,15 +1535,16 @@ InputFieldComponent.password = (0, import_react10.forwardRef)(function Password(
|
|
|
1365
1535
|
}
|
|
1366
1536
|
);
|
|
1367
1537
|
});
|
|
1368
|
-
InputFieldComponent.code = (0, import_react10.forwardRef)(function Password2(props, ref) {
|
|
1538
|
+
InputFieldComponent.code = (0, import_react10.forwardRef)(function Password2({ isSmall, ...props }, ref) {
|
|
1369
1539
|
const theme2 = (0, import_react_better_core9.useTheme)();
|
|
1370
1540
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1371
1541
|
InputFieldComponent,
|
|
1372
1542
|
{
|
|
1373
|
-
fontSize: 42,
|
|
1543
|
+
fontSize: isSmall ? 36 : 42,
|
|
1374
1544
|
fontWeight: 900,
|
|
1375
|
-
lineHeight: 50,
|
|
1376
|
-
paddingVertical: theme2.styles.space * 2,
|
|
1545
|
+
lineHeight: isSmall ? 42 : 50,
|
|
1546
|
+
paddingVertical: isSmall ? theme2.styles.space : theme2.styles.space * 2,
|
|
1547
|
+
paddingHorizontal: isSmall ? theme2.styles.gap : void 0,
|
|
1377
1548
|
textAlign: "center",
|
|
1378
1549
|
...props,
|
|
1379
1550
|
ref
|
|
@@ -1391,12 +1562,13 @@ var import_react11 = require("react");
|
|
|
1391
1562
|
var import_react_better_core10 = require("react-better-core");
|
|
1392
1563
|
var import_react_native9 = require("react-native");
|
|
1393
1564
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1394
|
-
function StatusBar({ darkStatusBar, hidden }) {
|
|
1565
|
+
function StatusBar({ darkStatusBar, hidden, barStyle, androidBarStyle, iOSBarStyle }) {
|
|
1395
1566
|
const theme2 = (0, import_react_better_core10.useTheme)();
|
|
1396
1567
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1397
1568
|
import_react_native9.StatusBar,
|
|
1398
1569
|
{
|
|
1399
1570
|
backgroundColor: darkStatusBar ? theme2.colors.backgroundSecondary : void 0,
|
|
1571
|
+
barStyle: barStyle ?? (import_react_native9.Platform.OS === "android" ? androidBarStyle : iOSBarStyle),
|
|
1400
1572
|
hidden
|
|
1401
1573
|
}
|
|
1402
1574
|
);
|
|
@@ -1439,6 +1611,7 @@ var asyncStoragePlugin = (options) => ({
|
|
|
1439
1611
|
formatPhoneNumber,
|
|
1440
1612
|
generateAsyncStorage,
|
|
1441
1613
|
generateRandomString,
|
|
1614
|
+
getFormErrorObject,
|
|
1442
1615
|
getPluralWord,
|
|
1443
1616
|
lightenColor,
|
|
1444
1617
|
loaderControls,
|
|
@@ -1448,6 +1621,7 @@ var asyncStoragePlugin = (options) => ({
|
|
|
1448
1621
|
useBooleanState,
|
|
1449
1622
|
useDebounceState,
|
|
1450
1623
|
useDevice,
|
|
1624
|
+
useForm,
|
|
1451
1625
|
useKeyboard,
|
|
1452
1626
|
useLoader,
|
|
1453
1627
|
useLoaderControls,
|