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.mjs
CHANGED
|
@@ -145,7 +145,7 @@ var pressStrength = () => {
|
|
|
145
145
|
};
|
|
146
146
|
|
|
147
147
|
// src/utils/hooks.ts
|
|
148
|
-
import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
|
|
148
|
+
import { useCallback, useEffect as useEffect2, useMemo as useMemo2, useRef, useState } from "react";
|
|
149
149
|
import { Dimensions, Keyboard } from "react-native";
|
|
150
150
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
151
151
|
import { useBooleanState as useBooleanState2, useTheme } from "react-better-core";
|
|
@@ -420,6 +420,128 @@ function useComponentPropsGrouper(props, prefix) {
|
|
|
420
420
|
};
|
|
421
421
|
}, [props, prefix]);
|
|
422
422
|
}
|
|
423
|
+
function useForm(options) {
|
|
424
|
+
const { defaultValues, requiredFields, additional, onSubmit, validate } = options;
|
|
425
|
+
const inputFieldRefs = useRef(
|
|
426
|
+
{}
|
|
427
|
+
);
|
|
428
|
+
const [values, setValues] = useState(defaultValues);
|
|
429
|
+
const [errors, setErrors] = useState({});
|
|
430
|
+
const [isSubmitting, setIsSubmitting] = useBooleanState2();
|
|
431
|
+
const numberOfInputFields = Object.keys(defaultValues).length;
|
|
432
|
+
const setFieldValue = useCallback(
|
|
433
|
+
(field, value) => {
|
|
434
|
+
setValues((oldValue) => ({
|
|
435
|
+
...oldValue,
|
|
436
|
+
[field]: value
|
|
437
|
+
}));
|
|
438
|
+
setErrors((oldValue) => ({
|
|
439
|
+
...oldValue,
|
|
440
|
+
[field]: void 0
|
|
441
|
+
}));
|
|
442
|
+
},
|
|
443
|
+
[]
|
|
444
|
+
);
|
|
445
|
+
const setFieldsValue = useCallback((values2) => {
|
|
446
|
+
setValues((oldValue) => ({
|
|
447
|
+
...oldValue,
|
|
448
|
+
...values2
|
|
449
|
+
}));
|
|
450
|
+
setErrors((oldValue) => {
|
|
451
|
+
const newErrors = {};
|
|
452
|
+
for (const key in values2) newErrors[key] = void 0;
|
|
453
|
+
return newErrors;
|
|
454
|
+
});
|
|
455
|
+
}, []);
|
|
456
|
+
const focusField = useCallback((field) => {
|
|
457
|
+
inputFieldRefs.current[field]?.focus();
|
|
458
|
+
}, []);
|
|
459
|
+
const validateForm = useCallback(() => {
|
|
460
|
+
const validationErrors = validate?.(values) || {};
|
|
461
|
+
setErrors(validationErrors);
|
|
462
|
+
return validationErrors;
|
|
463
|
+
}, [validate, values]);
|
|
464
|
+
const onSubmitFunction = useCallback(
|
|
465
|
+
async (event) => {
|
|
466
|
+
event?.preventDefault();
|
|
467
|
+
setIsSubmitting.setTrue();
|
|
468
|
+
try {
|
|
469
|
+
const validationErrors = validateForm();
|
|
470
|
+
if (Object.keys(validationErrors).length === 0) {
|
|
471
|
+
await onSubmit?.(values);
|
|
472
|
+
} else {
|
|
473
|
+
const firstErrorField = Object.keys(validationErrors)[0];
|
|
474
|
+
focusField(firstErrorField);
|
|
475
|
+
}
|
|
476
|
+
} finally {
|
|
477
|
+
setIsSubmitting.setFalse();
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
[values, validateForm, onSubmit, focusField]
|
|
481
|
+
);
|
|
482
|
+
const getInputFieldProps = useCallback(
|
|
483
|
+
(field) => {
|
|
484
|
+
const thisInputFieldIndex = Object.keys(values).findIndex((key) => key === field);
|
|
485
|
+
const isLastInputField = thisInputFieldIndex === numberOfInputFields - 1;
|
|
486
|
+
return {
|
|
487
|
+
required: requiredFields?.includes(field),
|
|
488
|
+
value: values[field]?.toString() ?? "",
|
|
489
|
+
errorMessage: errors[field],
|
|
490
|
+
returnKeyLabel: isLastInputField ? additional?.lastInputFieldReturnKeyLabel ?? "done" : "next",
|
|
491
|
+
onPressEnter: () => {
|
|
492
|
+
if (isLastInputField) onSubmitFunction();
|
|
493
|
+
else inputFieldRefs.current[Object.keys(values)[thisInputFieldIndex + 1]]?.focus();
|
|
494
|
+
},
|
|
495
|
+
onChange: (value) => {
|
|
496
|
+
setFieldValue(field, value);
|
|
497
|
+
},
|
|
498
|
+
ref: (element) => {
|
|
499
|
+
if (!element) return;
|
|
500
|
+
inputFieldRefs.current[field] = element;
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
},
|
|
504
|
+
[values, setFieldValue, errors, requiredFields, additional, onSubmitFunction]
|
|
505
|
+
);
|
|
506
|
+
const reset = useCallback(() => {
|
|
507
|
+
setValues(defaultValues);
|
|
508
|
+
setErrors({});
|
|
509
|
+
}, [defaultValues]);
|
|
510
|
+
const isDirty = useMemo2(
|
|
511
|
+
() => Object.keys(defaultValues).some((key) => defaultValues[key] !== values[key]),
|
|
512
|
+
[defaultValues, values]
|
|
513
|
+
);
|
|
514
|
+
const isValid = useMemo2(() => {
|
|
515
|
+
const validationErrors = validate?.(values) || {};
|
|
516
|
+
return Object.keys(validationErrors).length === 0;
|
|
517
|
+
}, [validate, values]);
|
|
518
|
+
const canSubmit = useMemo2(() => {
|
|
519
|
+
const requiredFieldsHaveValues = requiredFields?.every((field) => values[field] !== void 0 && values[field] !== "") ?? true;
|
|
520
|
+
return isValid && requiredFieldsHaveValues;
|
|
521
|
+
}, [isValid, requiredFields]);
|
|
522
|
+
return {
|
|
523
|
+
values,
|
|
524
|
+
errors,
|
|
525
|
+
isSubmitting,
|
|
526
|
+
setFieldValue,
|
|
527
|
+
setFieldsValue,
|
|
528
|
+
getInputFieldProps,
|
|
529
|
+
focusField,
|
|
530
|
+
inputFieldRefs: inputFieldRefs.current,
|
|
531
|
+
validate: validateForm,
|
|
532
|
+
onSubmit: onSubmitFunction,
|
|
533
|
+
reset,
|
|
534
|
+
requiredFields,
|
|
535
|
+
isDirty,
|
|
536
|
+
isValid,
|
|
537
|
+
canSubmit
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// src/utils/functions.ts
|
|
542
|
+
var getFormErrorObject = (formValues) => {
|
|
543
|
+
return {};
|
|
544
|
+
};
|
|
423
545
|
|
|
424
546
|
// src/utils/asyncStorage.ts
|
|
425
547
|
import NativeAsyncStorage from "@react-native-async-storage/async-storage";
|
|
@@ -975,7 +1097,7 @@ Button2.text = ButtonComponent.text;
|
|
|
975
1097
|
var Button_default = Button2;
|
|
976
1098
|
|
|
977
1099
|
// src/components/ScreenHolder.tsx
|
|
978
|
-
import { memo as memo7, useCallback, useMemo as useMemo6 } from "react";
|
|
1100
|
+
import { memo as memo7, useCallback as useCallback2, useMemo as useMemo6 } from "react";
|
|
979
1101
|
import { KeyboardAvoidingView, Platform as Platform3, RefreshControl, ScrollView } from "react-native";
|
|
980
1102
|
import { useBooleanState as useBooleanState3, useTheme as useTheme6 } from "react-better-core";
|
|
981
1103
|
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
@@ -1005,7 +1127,7 @@ var ScreenHolderComponent = ({
|
|
|
1005
1127
|
}),
|
|
1006
1128
|
[]
|
|
1007
1129
|
);
|
|
1008
|
-
const onRefreshElement =
|
|
1130
|
+
const onRefreshElement = useCallback2(() => {
|
|
1009
1131
|
setIsRefreshing.setTrue();
|
|
1010
1132
|
onRefresh?.();
|
|
1011
1133
|
setTimeout(() => {
|
|
@@ -1141,15 +1263,15 @@ var Image_default = Image2;
|
|
|
1141
1263
|
import {
|
|
1142
1264
|
forwardRef,
|
|
1143
1265
|
memo as memo9,
|
|
1144
|
-
useCallback as
|
|
1266
|
+
useCallback as useCallback3,
|
|
1145
1267
|
useEffect as useEffect4,
|
|
1146
1268
|
useImperativeHandle,
|
|
1147
1269
|
useMemo as useMemo8,
|
|
1148
|
-
useRef,
|
|
1270
|
+
useRef as useRef2,
|
|
1149
1271
|
useState as useState2
|
|
1150
1272
|
} from "react";
|
|
1151
1273
|
import {
|
|
1152
|
-
TextInput
|
|
1274
|
+
TextInput as TextInput2
|
|
1153
1275
|
} from "react-native";
|
|
1154
1276
|
import {
|
|
1155
1277
|
darkenColor,
|
|
@@ -1185,6 +1307,8 @@ var InputFieldComponent = forwardRef(
|
|
|
1185
1307
|
fontWeight = 400,
|
|
1186
1308
|
lineHeight = 20,
|
|
1187
1309
|
textAlign,
|
|
1310
|
+
required,
|
|
1311
|
+
disabled,
|
|
1188
1312
|
paddingHorizontal,
|
|
1189
1313
|
paddingVertical,
|
|
1190
1314
|
onFocus,
|
|
@@ -1195,22 +1319,22 @@ var InputFieldComponent = forwardRef(
|
|
|
1195
1319
|
}, ref) => {
|
|
1196
1320
|
const theme2 = useTheme8();
|
|
1197
1321
|
const { colorTheme } = useBetterCoreContext3();
|
|
1198
|
-
const textInputRef =
|
|
1322
|
+
const textInputRef = useRef2(null);
|
|
1199
1323
|
const [internalValue, setInternalValue] = useState2(value?.toString() || defaultValue || "");
|
|
1200
1324
|
const [isFocused, setIsFocused] = useBooleanState4();
|
|
1201
1325
|
const borderWidth = 1;
|
|
1202
1326
|
const readyPaddingHorizontal = paddingHorizontal ?? theme2.styles.space;
|
|
1203
1327
|
const readyPaddingVertical = paddingVertical ? parseFloat(paddingVertical.toString()) : (theme2.styles.space + theme2.styles.gap) / 2;
|
|
1204
1328
|
const readyHeight = height ?? borderWidth + readyPaddingVertical + lineHeight + readyPaddingVertical + borderWidth;
|
|
1205
|
-
const onFocusElement =
|
|
1329
|
+
const onFocusElement = useCallback3((event) => {
|
|
1206
1330
|
setIsFocused.setTrue();
|
|
1207
1331
|
onFocus?.(event);
|
|
1208
1332
|
}, []);
|
|
1209
|
-
const onBlurElement =
|
|
1333
|
+
const onBlurElement = useCallback3((event) => {
|
|
1210
1334
|
setIsFocused.setFalse();
|
|
1211
1335
|
onBlur?.(event);
|
|
1212
1336
|
}, []);
|
|
1213
|
-
const onChangeText =
|
|
1337
|
+
const onChangeText = useCallback3(
|
|
1214
1338
|
(text) => {
|
|
1215
1339
|
setInternalValue(text);
|
|
1216
1340
|
onChange?.(text);
|
|
@@ -1241,111 +1365,124 @@ var InputFieldComponent = forwardRef(
|
|
|
1241
1365
|
[]
|
|
1242
1366
|
);
|
|
1243
1367
|
const prefixSuffixBackgroundColor = colorTheme === "light" ? darkenColor(theme2.colors.backgroundContent, 0.03) : lightenColor(theme2.colors.backgroundContent, 0.1);
|
|
1244
|
-
return /* @__PURE__ */ jsxs4(
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1368
|
+
return /* @__PURE__ */ jsxs4(
|
|
1369
|
+
Animate_default.View,
|
|
1370
|
+
{
|
|
1371
|
+
flex: 1,
|
|
1372
|
+
gap: theme2.styles.gap / 3,
|
|
1373
|
+
initialOpacity: 1,
|
|
1374
|
+
animateOpacity: disabled ? 0.6 : 1,
|
|
1375
|
+
children: [
|
|
1376
|
+
label && /* @__PURE__ */ jsxs4(View_default, { isRow: true, width: "100%", alignItems: "center", gap: 2, children: [
|
|
1377
|
+
/* @__PURE__ */ jsx9(Text_default, { fontSize: 14, color: theme2.colors.textSecondary, children: label }),
|
|
1378
|
+
required && /* @__PURE__ */ jsx9(Text_default, { color: theme2.colors.error, children: "*" })
|
|
1379
|
+
] }),
|
|
1380
|
+
/* @__PURE__ */ jsxs4(View_default, { isRow: true, position: "relative", alignItems: "center", flex: 1, height: readyHeight, children: [
|
|
1381
|
+
prefix && /* @__PURE__ */ jsx9(
|
|
1382
|
+
View_default,
|
|
1383
|
+
{
|
|
1384
|
+
isRow: true,
|
|
1385
|
+
height: "100%",
|
|
1386
|
+
backgroundColor: prefixSuffixBackgroundColor,
|
|
1387
|
+
alignItems: "center",
|
|
1388
|
+
borderWidth,
|
|
1389
|
+
borderRightWidth: 0,
|
|
1390
|
+
borderTopLeftRadius: theme2.styles.borderRadius,
|
|
1391
|
+
borderBottomLeftRadius: theme2.styles.borderRadius,
|
|
1392
|
+
borderColor: theme2.colors.border,
|
|
1393
|
+
paddingHorizontal: readyPaddingHorizontal,
|
|
1394
|
+
children: typeof prefix === "string" ? /* @__PURE__ */ jsx9(Text_default, { fontWeight: 700, children: prefix }) : prefix
|
|
1395
|
+
}
|
|
1396
|
+
),
|
|
1397
|
+
/* @__PURE__ */ jsx9(
|
|
1398
|
+
Animate_default.View,
|
|
1399
|
+
{
|
|
1400
|
+
flex: 1,
|
|
1401
|
+
backgroundColor: theme2.colors.backgroundContent,
|
|
1402
|
+
borderTopLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
|
|
1403
|
+
borderBottomLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
|
|
1404
|
+
borderTopRightRadius: suffix ? 0 : theme2.styles.borderRadius,
|
|
1405
|
+
borderBottomRightRadius: suffix ? 0 : theme2.styles.borderRadius,
|
|
1406
|
+
borderWidth,
|
|
1407
|
+
initialBorderColor: theme2.colors.border,
|
|
1408
|
+
animateBorderColor: isFocused ? theme2.colors.primary : isError ? theme2.colors.error : theme2.colors.border,
|
|
1409
|
+
overflow: "hidden",
|
|
1410
|
+
children: /* @__PURE__ */ jsx9(
|
|
1411
|
+
TextInput2,
|
|
1412
|
+
{
|
|
1413
|
+
style: textInputStyle,
|
|
1414
|
+
value: internalValue,
|
|
1415
|
+
defaultValue,
|
|
1416
|
+
autoCapitalize,
|
|
1417
|
+
autoComplete,
|
|
1418
|
+
autoCorrect,
|
|
1419
|
+
autoFocus,
|
|
1420
|
+
placeholder,
|
|
1421
|
+
placeholderTextColor: theme2.colors.textSecondary + "80",
|
|
1422
|
+
enterKeyHint: returnKeyLabel,
|
|
1423
|
+
returnKeyType,
|
|
1424
|
+
onSubmitEditing: onPressEnter,
|
|
1425
|
+
readOnly: !editable || disabled,
|
|
1426
|
+
textAlign,
|
|
1427
|
+
editable: !disabled,
|
|
1428
|
+
keyboardAppearance,
|
|
1429
|
+
keyboardType,
|
|
1430
|
+
cursorColor: theme2.colors.primary,
|
|
1431
|
+
selectionColor: theme2.colors.primary,
|
|
1432
|
+
secureTextEntry,
|
|
1433
|
+
onFocus: onFocusElement,
|
|
1434
|
+
onBlur: onBlurElement,
|
|
1435
|
+
onChangeText,
|
|
1436
|
+
onPress,
|
|
1437
|
+
ref: textInputRef
|
|
1438
|
+
}
|
|
1439
|
+
)
|
|
1440
|
+
}
|
|
1441
|
+
),
|
|
1442
|
+
suffix && /* @__PURE__ */ jsx9(
|
|
1443
|
+
View_default,
|
|
1278
1444
|
{
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
onSubmitEditing: onPressEnter,
|
|
1291
|
-
readOnly: !editable,
|
|
1292
|
-
textAlign,
|
|
1293
|
-
keyboardAppearance,
|
|
1294
|
-
keyboardType,
|
|
1295
|
-
cursorColor: theme2.colors.primary,
|
|
1296
|
-
selectionColor: theme2.colors.primary,
|
|
1297
|
-
secureTextEntry,
|
|
1298
|
-
onFocus: onFocusElement,
|
|
1299
|
-
onBlur: onBlurElement,
|
|
1300
|
-
onChangeText,
|
|
1301
|
-
onPress,
|
|
1302
|
-
ref: textInputRef
|
|
1445
|
+
isRow: true,
|
|
1446
|
+
height: "100%",
|
|
1447
|
+
backgroundColor: prefixSuffixBackgroundColor,
|
|
1448
|
+
alignItems: "center",
|
|
1449
|
+
borderWidth,
|
|
1450
|
+
borderLeftWidth: 0,
|
|
1451
|
+
borderTopRightRadius: theme2.styles.borderRadius,
|
|
1452
|
+
borderBottomRightRadius: theme2.styles.borderRadius,
|
|
1453
|
+
borderColor: theme2.colors.border,
|
|
1454
|
+
paddingHorizontal: readyPaddingHorizontal,
|
|
1455
|
+
children: typeof suffix === "string" ? /* @__PURE__ */ jsx9(Text_default, { fontWeight: 700, children: suffix }) : suffix
|
|
1303
1456
|
}
|
|
1304
1457
|
)
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
children: infoMessage
|
|
1334
|
-
}
|
|
1335
|
-
),
|
|
1336
|
-
errorMessage && /* @__PURE__ */ jsx9(
|
|
1337
|
-
Animate_default.Text,
|
|
1338
|
-
{
|
|
1339
|
-
fontSize: 14,
|
|
1340
|
-
color: theme2.colors.error,
|
|
1341
|
-
initialHeight: 0,
|
|
1342
|
-
initialOpacity: 0,
|
|
1343
|
-
animateHeight: 17,
|
|
1344
|
-
animateOpacity: 1,
|
|
1345
|
-
children: errorMessage
|
|
1346
|
-
}
|
|
1347
|
-
)
|
|
1348
|
-
] });
|
|
1458
|
+
] }),
|
|
1459
|
+
infoMessage && /* @__PURE__ */ jsx9(
|
|
1460
|
+
Animate_default.Text,
|
|
1461
|
+
{
|
|
1462
|
+
fontSize: 14,
|
|
1463
|
+
color: theme2.colors.textSecondary,
|
|
1464
|
+
initialHeight: 0,
|
|
1465
|
+
initialOpacity: 0,
|
|
1466
|
+
animateHeight: 17,
|
|
1467
|
+
animateOpacity: 1,
|
|
1468
|
+
children: infoMessage
|
|
1469
|
+
}
|
|
1470
|
+
),
|
|
1471
|
+
errorMessage && /* @__PURE__ */ jsx9(
|
|
1472
|
+
Animate_default.Text,
|
|
1473
|
+
{
|
|
1474
|
+
fontSize: 14,
|
|
1475
|
+
color: theme2.colors.error,
|
|
1476
|
+
initialHeight: 0,
|
|
1477
|
+
initialOpacity: 0,
|
|
1478
|
+
animateHeight: 17,
|
|
1479
|
+
animateOpacity: 1,
|
|
1480
|
+
children: errorMessage
|
|
1481
|
+
}
|
|
1482
|
+
)
|
|
1483
|
+
]
|
|
1484
|
+
}
|
|
1485
|
+
);
|
|
1349
1486
|
}
|
|
1350
1487
|
);
|
|
1351
1488
|
InputFieldComponent.email = forwardRef(function Email(props, ref) {
|
|
@@ -1451,6 +1588,7 @@ export {
|
|
|
1451
1588
|
formatPhoneNumber,
|
|
1452
1589
|
generateAsyncStorage,
|
|
1453
1590
|
generateRandomString,
|
|
1591
|
+
getFormErrorObject,
|
|
1454
1592
|
getPluralWord,
|
|
1455
1593
|
lightenColor2 as lightenColor,
|
|
1456
1594
|
loaderControls,
|
|
@@ -1460,6 +1598,7 @@ export {
|
|
|
1460
1598
|
useBooleanState5 as useBooleanState,
|
|
1461
1599
|
useDebounceState,
|
|
1462
1600
|
useDevice,
|
|
1601
|
+
useForm,
|
|
1463
1602
|
useKeyboard,
|
|
1464
1603
|
useLoader2 as useLoader,
|
|
1465
1604
|
useLoaderControls,
|