react-native-better-html 1.0.3 → 1.0.4

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,234 @@ 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, useImperativeHandle, useMemo as useMemo8 } 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
+ editable = true,
1148
+ autoFocus,
1149
+ autoCapitalize,
1150
+ autoComplete,
1151
+ autoCorrect,
1152
+ keyboardAppearance = "default",
1153
+ keyboardType,
1154
+ secureTextEntry,
1155
+ onFocus,
1156
+ onBlur
1157
+ }, ref) => {
1158
+ const theme2 = useTheme8();
1159
+ const { colorTheme } = useBetterCoreContext3();
1160
+ const [isFocused, setIsFocused] = useBooleanState4();
1161
+ const paddingHorizontal = theme2.styles.space;
1162
+ const paddingVertical = (theme2.styles.space + theme2.styles.gap) / 2;
1163
+ const onFocusElement = useCallback2((event) => {
1164
+ setIsFocused.setTrue();
1165
+ onFocus?.(event);
1166
+ }, []);
1167
+ const onBlurElement = useCallback2((event) => {
1168
+ setIsFocused.setFalse();
1169
+ onBlur?.(event);
1170
+ }, []);
1171
+ const textInputStyle = useMemo8(
1172
+ () => ({
1173
+ flex: 1,
1174
+ fontSize: 16,
1175
+ lineHeight: 20,
1176
+ color: theme2.colors.textPrimary,
1177
+ paddingHorizontal,
1178
+ paddingVertical
1179
+ }),
1180
+ [theme2.colors, paddingHorizontal, paddingVertical]
1181
+ );
1182
+ useImperativeHandle(
1183
+ ref,
1184
+ () => {
1185
+ return {};
1186
+ },
1187
+ []
1188
+ );
1189
+ const prefixSuffixBackgroundColor = colorTheme === "light" ? darkenColor(theme2.colors.backgroundContent, 0.03) : lightenColor(theme2.colors.backgroundContent, 0.1);
1190
+ return /* @__PURE__ */ jsxs4(View_default, { isRow: true, position: "relative", alignItems: "center", children: [
1191
+ prefix && /* @__PURE__ */ jsx9(
1192
+ View_default,
1193
+ {
1194
+ isRow: true,
1195
+ height: "100%",
1196
+ backgroundColor: prefixSuffixBackgroundColor,
1197
+ alignItems: "center",
1198
+ borderWidth: 1,
1199
+ borderRightWidth: 0,
1200
+ borderTopLeftRadius: theme2.styles.borderRadius,
1201
+ borderBottomLeftRadius: theme2.styles.borderRadius,
1202
+ borderColor: theme2.colors.border,
1203
+ paddingHorizontal,
1204
+ children: /* @__PURE__ */ jsx9(Text_default, { fontWeight: 700, children: prefix })
1205
+ }
1206
+ ),
1207
+ /* @__PURE__ */ jsx9(
1208
+ Animate_default.View,
1209
+ {
1210
+ flex: 1,
1211
+ backgroundColor: theme2.colors.backgroundContent,
1212
+ borderTopLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
1213
+ borderBottomLeftRadius: prefix ? 0 : theme2.styles.borderRadius,
1214
+ borderTopRightRadius: suffix ? 0 : theme2.styles.borderRadius,
1215
+ borderBottomRightRadius: suffix ? 0 : theme2.styles.borderRadius,
1216
+ borderWidth: 1,
1217
+ initialBorderColor: theme2.colors.border,
1218
+ animateBorderColor: isFocused ? theme2.colors.primary : theme2.colors.border,
1219
+ overflow: "hidden",
1220
+ children: /* @__PURE__ */ jsx9(
1221
+ TextInput,
1222
+ {
1223
+ style: textInputStyle,
1224
+ defaultValue,
1225
+ autoCapitalize,
1226
+ autoComplete,
1227
+ autoCorrect,
1228
+ autoFocus,
1229
+ placeholder,
1230
+ placeholderTextColor: theme2.colors.textSecondary + "80",
1231
+ readOnly: !editable,
1232
+ keyboardAppearance,
1233
+ keyboardType,
1234
+ cursorColor: theme2.colors.primary,
1235
+ selectionColor: theme2.colors.primary,
1236
+ secureTextEntry,
1237
+ onFocus: onFocusElement,
1238
+ onBlur: onBlurElement
1239
+ }
1240
+ )
1241
+ }
1242
+ ),
1243
+ suffix && /* @__PURE__ */ jsx9(
1244
+ View_default,
1245
+ {
1246
+ isRow: true,
1247
+ height: "100%",
1248
+ backgroundColor: prefixSuffixBackgroundColor,
1249
+ alignItems: "center",
1250
+ borderWidth: 1,
1251
+ borderLeftWidth: 0,
1252
+ borderTopRightRadius: theme2.styles.borderRadius,
1253
+ borderBottomRightRadius: theme2.styles.borderRadius,
1254
+ borderColor: theme2.colors.border,
1255
+ paddingHorizontal,
1256
+ children: /* @__PURE__ */ jsx9(Text_default, { fontWeight: 700, children: suffix })
1257
+ }
1258
+ )
1259
+ ] });
1260
+ }
1261
+ );
1262
+ InputFieldComponent.email = forwardRef(function Email(props, ref) {
1263
+ return /* @__PURE__ */ jsx9(
1264
+ InputFieldComponent,
1265
+ {
1266
+ placeholder: "your@email.here",
1267
+ autoComplete: "email",
1268
+ keyboardType: "email-address",
1269
+ autoCapitalize: "none",
1270
+ autoCorrect: false,
1271
+ ...props,
1272
+ ref
1273
+ }
1274
+ );
1275
+ });
1276
+ InputFieldComponent.password = forwardRef(function Password(props, ref) {
1277
+ return /* @__PURE__ */ jsx9(
1278
+ InputFieldComponent,
1279
+ {
1280
+ secureTextEntry: true,
1281
+ placeholder: "******",
1282
+ autoCapitalize: "none",
1283
+ autoComplete: "password",
1284
+ autoCorrect: false,
1285
+ ...props,
1286
+ ref
1287
+ }
1288
+ );
1289
+ });
1290
+ var InputField = memo9(InputFieldComponent);
1291
+ InputField.email = InputFieldComponent.email;
1292
+ InputField.password = InputFieldComponent.password;
1293
+ var InputField_default = InputField;
1294
+
1018
1295
  // src/plugins/asyncStorage.ts
1019
1296
  var defaultAsyncStoragePluginOptions = {};
1020
1297
  var asyncStoragePlugin = (options) => ({
@@ -1031,6 +1308,8 @@ export {
1031
1308
  Animate_default as Animate,
1032
1309
  BetterComponentsProvider_default as BetterComponentsProvider,
1033
1310
  Button_default as Button,
1311
+ Image_default as Image,
1312
+ InputField_default as InputField,
1034
1313
  Loader_default as Loader,
1035
1314
  ScreenHolder_default as ScreenHolder,
1036
1315
  Text_default as Text,
@@ -1038,7 +1317,7 @@ export {
1038
1317
  asyncStoragePlugin,
1039
1318
  colorThemeControls,
1040
1319
  countries,
1041
- darkenColor,
1320
+ darkenColor2 as darkenColor,
1042
1321
  defaultAsyncStoragePluginOptions,
1043
1322
  desaturateColor,
1044
1323
  eventPreventDefault,
@@ -1048,16 +1327,17 @@ export {
1048
1327
  generateAsyncStorage,
1049
1328
  generateRandomString,
1050
1329
  getPluralWord,
1051
- lightenColor,
1330
+ lightenColor2 as lightenColor,
1052
1331
  loaderControls,
1053
1332
  pressStrength,
1054
1333
  saturateColor,
1055
1334
  useBetterComponentsContext,
1056
- useBooleanState3 as useBooleanState,
1335
+ useBooleanState5 as useBooleanState,
1057
1336
  useDebounceState,
1058
1337
  useDevice,
1338
+ useKeyboard,
1059
1339
  useLoader2 as useLoader,
1060
1340
  useLoaderControls,
1061
- useTheme7 as useTheme
1341
+ useTheme9 as useTheme
1062
1342
  };
1063
1343
  //# sourceMappingURL=index.mjs.map