react-native-better-html 1.0.3 → 1.0.5

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.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  // src/index.ts
2
2
  import {
3
- useTheme as useTheme7,
3
+ useTheme as useTheme9,
4
4
  useLoader as useLoader2,
5
5
  useLoaderControls,
6
6
  countries,
7
- lightenColor,
8
- darkenColor,
7
+ lightenColor as lightenColor2,
8
+ darkenColor as darkenColor2,
9
9
  saturateColor,
10
10
  desaturateColor,
11
11
  generateRandomString,
@@ -14,7 +14,7 @@ import {
14
14
  eventStopPropagation,
15
15
  eventPreventStop,
16
16
  getPluralWord,
17
- useBooleanState as useBooleanState3,
17
+ useBooleanState as useBooleanState5,
18
18
  useDebounceState,
19
19
  loaderControls,
20
20
  colorThemeControls
@@ -145,10 +145,10 @@ var pressStrength = () => {
145
145
  };
146
146
 
147
147
  // src/utils/hooks.ts
148
- import { useMemo as useMemo2 } from "react";
149
- import { Dimensions } from "react-native";
148
+ import { useEffect as useEffect2, useMemo as useMemo2, useState } from "react";
149
+ import { Dimensions, Keyboard } from "react-native";
150
150
  import { useSafeAreaInsets } from "react-native-safe-area-context";
151
- import { useTheme } from "react-better-core";
151
+ import { useBooleanState as useBooleanState2, useTheme } from "react-better-core";
152
152
 
153
153
  // src/constants/css.ts
154
154
  var cssProps = /* @__PURE__ */ new Set([
@@ -365,6 +365,36 @@ function useDevice() {
365
365
  isSmallDevice
366
366
  };
367
367
  }
368
+ function useKeyboard() {
369
+ const [keyboardOpened, setKeyboardOpened] = useBooleanState2();
370
+ const [keyboardWillOpen, setKeyboardWillOpen] = useBooleanState2();
371
+ const [keyboardHeight, setKeyboardHeight] = useState(0);
372
+ useEffect2(() => {
373
+ const keyboardDidShow = (event) => {
374
+ setKeyboardOpened.setTrue();
375
+ setKeyboardHeight(event.endCoordinates.height);
376
+ };
377
+ const keyboardDidHide = () => {
378
+ setKeyboardOpened.setFalse();
379
+ setKeyboardHeight(0);
380
+ };
381
+ const willShowSubscription = Keyboard.addListener("keyboardWillShow", setKeyboardWillOpen.setTrue);
382
+ const willHideSubscription = Keyboard.addListener("keyboardWillHide", setKeyboardWillOpen.setFalse);
383
+ const didShowSubscription = Keyboard.addListener("keyboardDidShow", keyboardDidShow);
384
+ const didHideSubscription = Keyboard.addListener("keyboardDidHide", keyboardDidHide);
385
+ return () => {
386
+ willShowSubscription.remove();
387
+ willHideSubscription.remove();
388
+ didShowSubscription.remove();
389
+ didHideSubscription.remove();
390
+ };
391
+ }, []);
392
+ return {
393
+ isOpened: keyboardOpened,
394
+ willOpen: keyboardWillOpen,
395
+ height: keyboardHeight
396
+ };
397
+ }
368
398
  function useComponentPropsGrouper(props, prefix) {
369
399
  return useMemo2(() => {
370
400
  const style = {};
@@ -683,6 +713,7 @@ var Text_default = Text2;
683
713
 
684
714
  // src/components/Button.tsx
685
715
  import { memo as memo6 } from "react";
716
+ import { Platform as Platform2 } from "react-native";
686
717
  import { useLoader, useTheme as useTheme5 } from "react-better-core";
687
718
 
688
719
  // src/components/Animate.tsx
@@ -844,6 +875,7 @@ var ButtonComponent = function Button({
844
875
  const color = textColor ?? theme2.colors.base;
845
876
  const paddingVertical = props.paddingVertical ? parseFloat(props.paddingVertical.toString()) : theme2.styles.space;
846
877
  const paddingHorizontal = props.paddingHorizontal ? parseFloat(props.paddingHorizontal.toString()) : theme2.styles.space + theme2.styles.gap;
878
+ const buttonHeight = paddingVertical + lineHeight + paddingVertical;
847
879
  return /* @__PURE__ */ jsx6(
848
880
  Animate_default.View,
849
881
  {
@@ -857,6 +889,7 @@ var ButtonComponent = function Button({
857
889
  {
858
890
  position: "relative",
859
891
  width: !isSmall ? "100%" : void 0,
892
+ height: Platform2.OS === "android" ? buttonHeight : void 0,
860
893
  alignItems: "center",
861
894
  justifyContent: "center",
862
895
  backgroundColor: theme2.colors.primary,
@@ -884,7 +917,7 @@ var ButtonComponent = function Button({
884
917
  {
885
918
  position: "absolute",
886
919
  width: "100%",
887
- height: paddingVertical + lineHeight + paddingVertical,
920
+ height: buttonHeight,
888
921
  left: paddingHorizontal,
889
922
  alignItems: "center",
890
923
  justifyContent: "center",
@@ -942,9 +975,9 @@ Button2.text = ButtonComponent.text;
942
975
  var Button_default = Button2;
943
976
 
944
977
  // src/components/ScreenHolder.tsx
945
- import { memo as memo7, useCallback } from "react";
946
- import { RefreshControl, ScrollView } from "react-native";
947
- import { useBooleanState as useBooleanState2, useTheme as useTheme6 } from "react-better-core";
978
+ import { memo as memo7, useCallback, useMemo as useMemo6 } from "react";
979
+ import { KeyboardAvoidingView, Platform as Platform3, RefreshControl, ScrollView } from "react-native";
980
+ import { useBooleanState as useBooleanState3, useTheme as useTheme6 } from "react-better-core";
948
981
  import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
949
982
  var ScreenHolderComponent = ({
950
983
  noScroll,
@@ -957,11 +990,19 @@ var ScreenHolderComponent = ({
957
990
  insideBottomSafeArea,
958
991
  bottomSpace = 0,
959
992
  footer,
993
+ keepFooterOnKeyboardOpened,
960
994
  children
961
995
  }) => {
962
996
  const theme2 = useTheme6();
963
997
  const device = useDevice();
964
- const [isRefreshing, setIsRefreshing] = useBooleanState2();
998
+ const keyboard = useKeyboard();
999
+ const [isRefreshing, setIsRefreshing] = useBooleanState3();
1000
+ const keyboardAvoidingViewStyle = useMemo6(
1001
+ () => ({
1002
+ flex: 1
1003
+ }),
1004
+ []
1005
+ );
965
1006
  const onRefreshElement = useCallback(() => {
966
1007
  setIsRefreshing.setTrue();
967
1008
  onRefresh?.();
@@ -976,21 +1017,29 @@ var ScreenHolderComponent = ({
976
1017
  flex: 1,
977
1018
  paddingHorizontal: !noSideSpace ? theme2.styles.space : void 0,
978
1019
  paddingTop: theme2.styles.gap + (insideTopSafeArea ? device.safeArea.afterCalculations.top : 0),
979
- paddingBottom: bottomSpace + (insideBottomSafeArea ? device.safeArea.afterCalculations.bottom : 0),
1020
+ paddingBottom: Platform3.OS === "ios" && keyboard.isOpened ? device.safeArea.afterCalculations.top : bottomSpace + (insideBottomSafeArea ? device.safeArea.afterCalculations.bottom : 0),
980
1021
  children
981
1022
  }
982
1023
  );
983
1024
  const withRefresh = onRefresh || onRefreshEnd;
984
- return /* @__PURE__ */ jsxs3(View_default, { flex: 1, backgroundColor: backgroundColor ?? theme2.colors.backgroundBase, children: [
985
- /* @__PURE__ */ jsx7(View_default, { flex: 1, children: noScroll ? content : /* @__PURE__ */ jsx7(
986
- ScrollView,
987
- {
988
- refreshControl: withRefresh ? /* @__PURE__ */ jsx7(RefreshControl, { refreshing: isRefreshing, onRefresh: onRefreshElement }) : void 0,
989
- children: content
990
- }
991
- ) }),
992
- footer && /* @__PURE__ */ jsx7(View_default, { children: footer })
993
- ] });
1025
+ return /* @__PURE__ */ jsx7(View_default, { flex: 1, backgroundColor: backgroundColor ?? theme2.colors.backgroundBase, children: /* @__PURE__ */ jsxs3(
1026
+ KeyboardAvoidingView,
1027
+ {
1028
+ style: keyboardAvoidingViewStyle,
1029
+ keyboardVerticalOffset: keepFooterOnKeyboardOpened ? Platform3.OS === "ios" ? device.safeArea.afterCalculations.bottom : theme2.styles.gap : void 0,
1030
+ behavior: Platform3.OS === "ios" ? "padding" : "height",
1031
+ children: [
1032
+ /* @__PURE__ */ jsx7(View_default, { flex: 1, children: noScroll ? content : /* @__PURE__ */ jsx7(
1033
+ ScrollView,
1034
+ {
1035
+ refreshControl: withRefresh ? /* @__PURE__ */ jsx7(RefreshControl, { refreshing: isRefreshing, onRefresh: onRefreshElement }) : void 0,
1036
+ children: content
1037
+ }
1038
+ ) }),
1039
+ keepFooterOnKeyboardOpened || (Platform3.OS === "ios" ? !keyboard.willOpen : !keyboard.isOpened) ? footer && /* @__PURE__ */ jsx7(View_default, { children: footer }) : /* @__PURE__ */ jsx7(View_default, { width: "100%", height: device.safeArea.afterCalculations.bottom })
1040
+ ]
1041
+ }
1042
+ ) });
994
1043
  };
995
1044
  ScreenHolderComponent.footer = function Footer({
996
1045
  noSideSpace,
@@ -1015,6 +1064,250 @@ var ScreenHolder = memo7(ScreenHolderComponent);
1015
1064
  ScreenHolder.footer = ScreenHolderComponent.footer;
1016
1065
  var ScreenHolder_default = ScreenHolder;
1017
1066
 
1067
+ // src/components/Image.tsx
1068
+ import { memo as memo8, useEffect as useEffect3, useMemo as useMemo7 } from "react";
1069
+ import { useBetterCoreContext as useBetterCoreContext2, useTheme as useTheme7 } from "react-better-core";
1070
+ import {
1071
+ Image as NativeImage
1072
+ } from "react-native";
1073
+ import { jsx as jsx8 } from "react/jsx-runtime";
1074
+ var ImageComponent = function Image({ name, source, withDevFittingMode, ...props }) {
1075
+ const { assets: assets2 } = useBetterCoreContext2();
1076
+ const style = useMemo7(
1077
+ () => ({
1078
+ width: 100,
1079
+ height: 100,
1080
+ ...withDevFittingMode ? {
1081
+ borderWidth: 1,
1082
+ borderColor: "#eb39f7"
1083
+ } : {},
1084
+ ...props
1085
+ }),
1086
+ [withDevFittingMode, props]
1087
+ );
1088
+ useEffect3(() => {
1089
+ if (!name) return;
1090
+ if (!assets2[name.toString()])
1091
+ console.warn(
1092
+ `The asset \`${name}\` you are trying to use does not exist. Make sure to add it to the \`assets\` object in \`<BetterComponentsProvider>\` config value prop.`
1093
+ );
1094
+ }, [assets2, name]);
1095
+ return /* @__PURE__ */ jsx8(NativeImage, { source: name ? assets2[name.toString()] : source, style, ...props });
1096
+ };
1097
+ ImageComponent.profileImage = function ProfileImage({ size = 50, letters, backgroundColor, ...props }) {
1098
+ const theme2 = useTheme7();
1099
+ return letters ? /* @__PURE__ */ jsx8(
1100
+ View_default,
1101
+ {
1102
+ width: size,
1103
+ height: size,
1104
+ backgroundColor: backgroundColor ?? theme2.colors.backgroundSecondary,
1105
+ borderWidth: 1,
1106
+ borderColor: theme2.colors.border,
1107
+ borderRadius: 999,
1108
+ alignItems: "center",
1109
+ justifyContent: "center",
1110
+ ...props,
1111
+ children: /* @__PURE__ */ jsx8(Text_default, { fontSize: size / 2.5, fontWeight: 700, marginTop: 1, children: letters.toUpperCase().slice(0, 2) })
1112
+ }
1113
+ ) : /* @__PURE__ */ jsx8(
1114
+ ImageComponent,
1115
+ {
1116
+ width: size,
1117
+ height: size,
1118
+ borderWidth: 1,
1119
+ borderColor: theme2.colors.border,
1120
+ borderRadius: 999,
1121
+ objectFit: "cover",
1122
+ ...props
1123
+ }
1124
+ );
1125
+ };
1126
+ var Image2 = memo8(ImageComponent);
1127
+ Image2.profileImage = ImageComponent.profileImage;
1128
+ var Image_default = Image2;
1129
+
1130
+ // src/components/InputField.tsx
1131
+ import { forwardRef, memo as memo9, useCallback as useCallback2, useEffect as useEffect4, useImperativeHandle, useMemo as useMemo8, useState as useState2 } from "react";
1132
+ import { TextInput } from "react-native";
1133
+ import {
1134
+ darkenColor,
1135
+ lightenColor,
1136
+ useBetterCoreContext as useBetterCoreContext3,
1137
+ useBooleanState as useBooleanState4,
1138
+ useTheme as useTheme8
1139
+ } from "react-better-core";
1140
+ import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
1141
+ var InputFieldComponent = forwardRef(
1142
+ ({
1143
+ placeholder,
1144
+ prefix,
1145
+ suffix,
1146
+ defaultValue,
1147
+ value,
1148
+ editable = true,
1149
+ autoFocus,
1150
+ autoCapitalize,
1151
+ autoComplete,
1152
+ autoCorrect,
1153
+ keyboardAppearance = "default",
1154
+ keyboardType,
1155
+ secureTextEntry,
1156
+ onFocus,
1157
+ onBlur,
1158
+ onChange
1159
+ }, ref) => {
1160
+ const theme2 = useTheme8();
1161
+ const { colorTheme } = useBetterCoreContext3();
1162
+ const [internalValue, setInternalValue] = useState2(value?.toString() || defaultValue || "");
1163
+ const [isFocused, setIsFocused] = useBooleanState4();
1164
+ const paddingHorizontal = theme2.styles.space;
1165
+ const paddingVertical = (theme2.styles.space + theme2.styles.gap) / 2;
1166
+ const onFocusElement = useCallback2((event) => {
1167
+ setIsFocused.setTrue();
1168
+ onFocus?.(event);
1169
+ }, []);
1170
+ const onBlurElement = useCallback2((event) => {
1171
+ setIsFocused.setFalse();
1172
+ onBlur?.(event);
1173
+ }, []);
1174
+ const onChangeText = useCallback2(
1175
+ (text) => {
1176
+ setInternalValue(text);
1177
+ onChange?.(text);
1178
+ },
1179
+ [onChange]
1180
+ );
1181
+ const textInputStyle = useMemo8(
1182
+ () => ({
1183
+ flex: 1,
1184
+ fontSize: 16,
1185
+ lineHeight: 20,
1186
+ color: theme2.colors.textPrimary,
1187
+ paddingHorizontal,
1188
+ paddingVertical
1189
+ }),
1190
+ [theme2.colors, paddingHorizontal, paddingVertical]
1191
+ );
1192
+ useEffect4(() => {
1193
+ if (value === void 0) return;
1194
+ setInternalValue(value.toString());
1195
+ }, [value]);
1196
+ useImperativeHandle(
1197
+ ref,
1198
+ () => {
1199
+ return {};
1200
+ },
1201
+ []
1202
+ );
1203
+ const prefixSuffixBackgroundColor = colorTheme === "light" ? darkenColor(theme2.colors.backgroundContent, 0.03) : lightenColor(theme2.colors.backgroundContent, 0.1);
1204
+ return /* @__PURE__ */ jsxs4(View_default, { isRow: true, position: "relative", alignItems: "center", children: [
1205
+ prefix && /* @__PURE__ */ jsx9(
1206
+ View_default,
1207
+ {
1208
+ isRow: true,
1209
+ height: "100%",
1210
+ backgroundColor: prefixSuffixBackgroundColor,
1211
+ alignItems: "center",
1212
+ borderWidth: 1,
1213
+ borderRightWidth: 0,
1214
+ borderTopLeftRadius: theme2.styles.borderRadius,
1215
+ borderBottomLeftRadius: theme2.styles.borderRadius,
1216
+ borderColor: theme2.colors.border,
1217
+ paddingHorizontal,
1218
+ children: /* @__PURE__ */ jsx9(Text_default, { fontWeight: 700, children: prefix })
1219
+ }
1220
+ ),
1221
+ /* @__PURE__ */ jsx9(
1222
+ Animate_default.View,
1223
+ {
1224
+ flex: 1,
1225
+ backgroundColor: theme2.colors.backgroundContent,
1226
+ borderTopLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
1227
+ borderBottomLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
1228
+ borderTopRightRadius: suffix ? 0 : theme2.styles.borderRadius,
1229
+ borderBottomRightRadius: suffix ? 0 : theme2.styles.borderRadius,
1230
+ borderWidth: 1,
1231
+ initialBorderColor: theme2.colors.border,
1232
+ animateBorderColor: isFocused ? theme2.colors.primary : theme2.colors.border,
1233
+ overflow: "hidden",
1234
+ children: /* @__PURE__ */ jsx9(
1235
+ TextInput,
1236
+ {
1237
+ style: textInputStyle,
1238
+ value: internalValue,
1239
+ defaultValue,
1240
+ autoCapitalize,
1241
+ autoComplete,
1242
+ autoCorrect,
1243
+ autoFocus,
1244
+ placeholder,
1245
+ placeholderTextColor: theme2.colors.textSecondary + "80",
1246
+ readOnly: !editable,
1247
+ keyboardAppearance,
1248
+ keyboardType,
1249
+ cursorColor: theme2.colors.primary,
1250
+ selectionColor: theme2.colors.primary,
1251
+ secureTextEntry,
1252
+ onFocus: onFocusElement,
1253
+ onBlur: onBlurElement,
1254
+ onChangeText
1255
+ }
1256
+ )
1257
+ }
1258
+ ),
1259
+ suffix && /* @__PURE__ */ jsx9(
1260
+ View_default,
1261
+ {
1262
+ isRow: true,
1263
+ height: "100%",
1264
+ backgroundColor: prefixSuffixBackgroundColor,
1265
+ alignItems: "center",
1266
+ borderWidth: 1,
1267
+ borderLeftWidth: 0,
1268
+ borderTopRightRadius: theme2.styles.borderRadius,
1269
+ borderBottomRightRadius: theme2.styles.borderRadius,
1270
+ borderColor: theme2.colors.border,
1271
+ paddingHorizontal,
1272
+ children: /* @__PURE__ */ jsx9(Text_default, { fontWeight: 700, children: suffix })
1273
+ }
1274
+ )
1275
+ ] });
1276
+ }
1277
+ );
1278
+ InputFieldComponent.email = forwardRef(function Email(props, ref) {
1279
+ return /* @__PURE__ */ jsx9(
1280
+ InputFieldComponent,
1281
+ {
1282
+ placeholder: "your@email.here",
1283
+ autoComplete: "email",
1284
+ keyboardType: "email-address",
1285
+ autoCapitalize: "none",
1286
+ autoCorrect: false,
1287
+ ...props,
1288
+ ref
1289
+ }
1290
+ );
1291
+ });
1292
+ InputFieldComponent.password = forwardRef(function Password(props, ref) {
1293
+ return /* @__PURE__ */ jsx9(
1294
+ InputFieldComponent,
1295
+ {
1296
+ secureTextEntry: true,
1297
+ placeholder: "******",
1298
+ autoCapitalize: "none",
1299
+ autoComplete: "password",
1300
+ autoCorrect: false,
1301
+ ...props,
1302
+ ref
1303
+ }
1304
+ );
1305
+ });
1306
+ var InputField = memo9(InputFieldComponent);
1307
+ InputField.email = InputFieldComponent.email;
1308
+ InputField.password = InputFieldComponent.password;
1309
+ var InputField_default = InputField;
1310
+
1018
1311
  // src/plugins/asyncStorage.ts
1019
1312
  var defaultAsyncStoragePluginOptions = {};
1020
1313
  var asyncStoragePlugin = (options) => ({
@@ -1031,6 +1324,8 @@ export {
1031
1324
  Animate_default as Animate,
1032
1325
  BetterComponentsProvider_default as BetterComponentsProvider,
1033
1326
  Button_default as Button,
1327
+ Image_default as Image,
1328
+ InputField_default as InputField,
1034
1329
  Loader_default as Loader,
1035
1330
  ScreenHolder_default as ScreenHolder,
1036
1331
  Text_default as Text,
@@ -1038,7 +1333,7 @@ export {
1038
1333
  asyncStoragePlugin,
1039
1334
  colorThemeControls,
1040
1335
  countries,
1041
- darkenColor,
1336
+ darkenColor2 as darkenColor,
1042
1337
  defaultAsyncStoragePluginOptions,
1043
1338
  desaturateColor,
1044
1339
  eventPreventDefault,
@@ -1048,16 +1343,17 @@ export {
1048
1343
  generateAsyncStorage,
1049
1344
  generateRandomString,
1050
1345
  getPluralWord,
1051
- lightenColor,
1346
+ lightenColor2 as lightenColor,
1052
1347
  loaderControls,
1053
1348
  pressStrength,
1054
1349
  saturateColor,
1055
1350
  useBetterComponentsContext,
1056
- useBooleanState3 as useBooleanState,
1351
+ useBooleanState5 as useBooleanState,
1057
1352
  useDebounceState,
1058
1353
  useDevice,
1354
+ useKeyboard,
1059
1355
  useLoader2 as useLoader,
1060
1356
  useLoaderControls,
1061
- useTheme7 as useTheme
1357
+ useTheme9 as useTheme
1062
1358
  };
1063
1359
  //# sourceMappingURL=index.mjs.map