react-better-html 1.1.43 → 1.1.45

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.
@@ -23,11 +23,11 @@ export type DropdownProps<Value, Data> = {
23
23
  inputFieldClassName?: string;
24
24
  withSearch?: boolean;
25
25
  withDebounce?: boolean;
26
- withoutClearButton?: boolean;
27
26
  /** @default 0.5s */
28
27
  debounceDelay?: number;
29
28
  debounceIsLoading?: boolean;
30
29
  debounceMinimumSymbolsRequired?: number;
30
+ withoutClearButton?: boolean;
31
31
  onChange?: (value: Value | undefined) => void;
32
32
  onChangeSearch?: (query: string) => void;
33
33
  renderOption?: (option: DropdownOption<Value, Data>, index: number, isSelected: boolean) => React.ReactNode;
@@ -14,7 +14,7 @@ const Icon_1 = __importDefault(require("./Icon"));
14
14
  const Button_1 = __importDefault(require("./Button"));
15
15
  const Loader_1 = __importDefault(require("./Loader"));
16
16
  const BetterHtmlProvider_1 = require("./BetterHtmlProvider");
17
- const DropdownComponent = (0, react_1.forwardRef)(function Dropdown({ label, errorText, infoText, required, disabled, options, value: controlledValue, defaultValue, placeholder = "Select an option", leftIcon, inputFieldClassName, withSearch, withDebounce, withoutClearButton, debounceDelay = 0.5, debounceIsLoading, debounceMinimumSymbolsRequired, onChange, onChangeSearch, renderOption, ...props }, ref) {
17
+ const DropdownComponent = (0, react_1.forwardRef)(function Dropdown({ label, errorText, infoText, required, disabled, options, value: controlledValue, defaultValue, placeholder = "Select an option", leftIcon, inputFieldClassName, withSearch, withDebounce, debounceDelay = 0.5, debounceIsLoading, debounceMinimumSymbolsRequired, withoutClearButton, onChange, onChangeSearch, renderOption, ...props }, ref) {
18
18
  const theme = (0, BetterHtmlProvider_1.useTheme)();
19
19
  const dropdownHolderRef = (0, react_1.useRef)(null);
20
20
  const inputRef = (0, react_1.useRef)(null);
@@ -18,10 +18,10 @@ function Form({ form, submitButtonText, submitButtonLoaderName, submitButtonId,
18
18
  }, [form]);
19
19
  const SubmitButtonTag = isDestructive ? Button_1.default.destructive : Button_1.default;
20
20
  const submitButtonIsDisabledFinal = submitButtonIsDisabled || submitButtonIsDisabledInternal;
21
- return ((0, jsx_runtime_1.jsx)(Div_1.default, { ...props, children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: onSubmit, children: [gap !== undefined ? (0, jsx_runtime_1.jsx)(Div_1.default.column, { gap: gap, children: children }) : children, submitButtonText && ((0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", justifyContent: actionButtonsLocation === "left"
21
+ return ((0, jsx_runtime_1.jsx)(Div_1.default, { ...props, children: (0, jsx_runtime_1.jsxs)("form", { onSubmit: onSubmit ?? form?.onSubmit, children: [gap !== undefined ? (0, jsx_runtime_1.jsx)(Div_1.default.column, { gap: gap, children: children }) : children, submitButtonText && ((0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", justifyContent: actionButtonsLocation === "left"
22
22
  ? "flex-start"
23
23
  : actionButtonsLocation === "center"
24
24
  ? "center"
25
- : "flex-end", gap: theme.styles.gap, marginTop: theme.styles.space, children: [onClickCancel && (0, jsx_runtime_1.jsx)(Button_1.default.secondary, { text: "Cancel", onClick: onClickCancel }), (0, jsx_runtime_1.jsx)(SubmitButtonTag, { text: submitButtonText, isLoading: isSubmitting, loaderName: submitButtonLoaderName, disabled: submitButtonIsDisabledFinal, id: submitButtonId, isSubmit: true })] }))] }) }));
25
+ : "flex-end", gap: theme.styles.gap, marginTop: theme.styles.space, children: [onClickCancel && (0, jsx_runtime_1.jsx)(Button_1.default.secondary, { text: "Cancel", onClick: onClickCancel }), (0, jsx_runtime_1.jsx)(SubmitButtonTag, { text: submitButtonText, isLoading: isSubmitting || form?.isSubmitting, loaderName: submitButtonLoaderName, disabled: submitButtonIsDisabledFinal, id: submitButtonId, isSubmit: true })] }))] }) }));
26
26
  }
27
27
  exports.default = (0, react_1.memo)(Form);
@@ -8,7 +8,7 @@ type InternalToggleInputProps<Value> = {
8
8
  infoText?: string;
9
9
  value?: Value;
10
10
  onChange?: (checked: boolean, value?: Value) => void;
11
- } & OmitProps<React.ComponentProps<"input">, "style" | "value" | "ref" | "onChange" | "name"> & ComponentStyle & ComponentHoverStyle;
11
+ } & OmitProps<React.ComponentProps<"input">, "style" | "value" | "ref" | "onChange"> & ComponentStyle & ComponentHoverStyle;
12
12
  export type ToggleInputProps<Value> = ComponentPropWithRef<ToggleInputRef, OmitProps<InternalToggleInputProps<Value>, "type">>;
13
13
  type ToggleInputComponentType = <Value>(props: ToggleInputProps<Value>) => React.ReactElement;
14
14
  declare const _default: {
@@ -10,14 +10,18 @@ const hooks_1 = require("../utils/hooks");
10
10
  const Text_1 = __importDefault(require("./Text"));
11
11
  const Div_1 = __importDefault(require("./Div"));
12
12
  const Icon_1 = __importDefault(require("./Icon"));
13
+ const Label_1 = __importDefault(require("./Label"));
13
14
  const BetterHtmlProvider_1 = require("./BetterHtmlProvider");
15
+ const componentSize = 26;
16
+ const switchComponentBallGap = 3;
17
+ const switchComponentMouseDownDifference = 4;
14
18
  const InputElement = styled_components_1.default.input.withConfig({
15
19
  shouldForwardProp: (prop) => !["theme", "normalStyle", "hoverStyle"].includes(prop),
16
20
  }) `
17
21
  position: relative;
18
22
  appearance: none;
19
- width: 26px;
20
- height: 26px;
23
+ width: ${componentSize}px;
24
+ height: ${componentSize}px;
21
25
  background-color: ${(props) => props.theme.colors.backgroundContent};
22
26
  border: 1px solid ${(props) => props.theme.colors.border};
23
27
  border-radius: ${(props) => props.theme.styles.borderRadius / 2}px;
@@ -46,13 +50,15 @@ const InputElement = styled_components_1.default.input.withConfig({
46
50
  }
47
51
  `;
48
52
  const SwitchElement = styled_components_1.default.div.withConfig({
49
- shouldForwardProp: (prop) => !["theme", "checked", "disabled", "normalStyle", "hoverStyle"].includes(prop),
53
+ shouldForwardProp: (prop) => !["theme", "checked", "disabled", "isMouseDown", "normalStyle", "hoverStyle"].includes(prop),
50
54
  }) `
55
+ --width: ${(props) => componentSize * 2 - props.theme.styles.gap / 2}px;
56
+
51
57
  position: relative;
52
- width: 36px;
53
- height: 20px;
58
+ width: var(--width);
59
+ height: ${componentSize}px;
54
60
  background-color: ${(props) => (props.checked ? props.theme.colors.primary : props.theme.colors.border)};
55
- border-radius: 10px;
61
+ border-radius: 999px;
56
62
  cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")};
57
63
  opacity: ${(props) => (props.disabled ? 0.5 : 1)};
58
64
  transition: ${(props) => props.theme.styles.transition};
@@ -60,14 +66,18 @@ const SwitchElement = styled_components_1.default.div.withConfig({
60
66
  &::before {
61
67
  content: "";
62
68
  position: absolute;
63
- width: 16px;
64
- height: 16px;
65
- background-color: white;
66
- border-radius: 50%;
67
- top: 2px;
68
- left: 2px;
69
+ width: ${(props) => componentSize - switchComponentBallGap * 2 + (props.isMouseDown ? switchComponentMouseDownDifference : 0)}px;
70
+ height: ${componentSize - switchComponentBallGap * 2}px;
71
+ background-color: ${(props) => props.theme.colors.base};
72
+ border-radius: 999px;
73
+ top: ${switchComponentBallGap}px;
74
+ left: ${switchComponentBallGap}px;
75
+ transform: translateX(
76
+ ${(props) => props.checked
77
+ ? `calc(var(--width) - ${componentSize + (props.isMouseDown ? switchComponentMouseDownDifference : 0)}px)`
78
+ : "0px"}
79
+ );
69
80
  transition: ${(props) => props.theme.styles.transition};
70
- transform: translateX(${(props) => (props.checked ? "16px" : "0")});
71
81
  }
72
82
 
73
83
  ${(props) => props.normalStyle}
@@ -85,19 +95,19 @@ const ToggleInputComponent = (0, react_1.forwardRef)(function ToggleInput({ labe
85
95
  const restProps = (0, hooks_1.useComponentPropsWithoutStyle)(props);
86
96
  const [internalChecked, setInternalChecked] = (0, react_1.useState)(false);
87
97
  const onChangeElement = (0, react_1.useCallback)((event) => {
88
- const newValue = event.target.checked;
98
+ const newIsChecked = event.target.checked;
89
99
  if (controlledChecked === undefined)
90
- setInternalChecked(newValue);
91
- onChange?.(newValue, value);
100
+ setInternalChecked(newIsChecked);
101
+ onChange?.(newIsChecked, value);
92
102
  }, [onChange, controlledChecked, value]);
93
103
  const checked = controlledChecked ?? internalChecked;
94
104
  const onClickText = (0, react_1.useCallback)(() => {
95
- const newValue = !checked;
105
+ const newIsChecked = !checked;
96
106
  if (controlledChecked === undefined)
97
- setInternalChecked(newValue);
98
- onChange?.(newValue, value);
107
+ setInternalChecked(newIsChecked);
108
+ onChange?.(newIsChecked, value);
99
109
  }, [checked, controlledChecked, onChange, value]);
100
- return ((0, jsx_runtime_1.jsxs)(Div_1.default.column, { width: "100%", gap: theme.styles.gap / 2, ...styledComponentStylesWithExcluded, children: [label && ((0, jsx_runtime_1.jsxs)(Text_1.default, { as: "label", height: 16, fontSize: 14, color: errorText ? theme.colors.error : theme.colors.textSecondary, children: [label, required && ((0, jsx_runtime_1.jsxs)(Text_1.default, { as: "span", fontSize: 16, color: theme.colors.error, children: [" ", "*"] }))] })), (0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", gap: theme.styles.gap, children: [(0, jsx_runtime_1.jsxs)(Div_1.default.row, { position: "relative", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(InputElement, { theme: theme, type: props.type ?? "checkbox", checked: checked, onChange: onChangeElement, ...styledComponentStyles, ...dataProps, ...ariaProps, ...restProps }), props.type === "checkbox" ? ((0, jsx_runtime_1.jsx)(Icon_1.default, { name: "check", position: "absolute", top: "50%", left: "50%", color: theme.colors.base, size: 14, transform: `translate(-50%, -50%)${checked ? "" : " scale(0.4)"}`, opacity: checked ? 1 : 0, pointerEvents: "none", transition: theme.styles.transition })) : props.type === "radio" ? ((0, jsx_runtime_1.jsx)(Div_1.default, { position: "absolute", width: 10, height: 10, top: "50%", left: "50%", backgroundColor: theme.colors.base, borderRadius: 999, transform: `translate(-50%, -50%)${checked ? "" : " scale(0.4)"}`, opacity: checked ? 1 : 0, pointerEvents: "none" })) : undefined] }), text && ((0, jsx_runtime_1.jsx)(Text_1.default, { userSelect: "none", cursor: "pointer", onClick: onClickText, children: text }))] }), (errorText || infoText) && ((0, jsx_runtime_1.jsx)(Text_1.default, { as: "span", display: "block", fontSize: 14, color: errorText ? theme.colors.error : theme.colors.textSecondary, children: errorText || infoText }))] }));
110
+ return ((0, jsx_runtime_1.jsxs)(Div_1.default.column, { width: "100%", gap: theme.styles.gap / 2, ...styledComponentStylesWithExcluded, children: [label && (0, jsx_runtime_1.jsx)(Label_1.default, { text: label, required: required, isError: !!errorText }), (0, jsx_runtime_1.jsxs)(Div_1.default.row, { alignItems: "center", gap: theme.styles.gap, children: [(0, jsx_runtime_1.jsxs)(Div_1.default.row, { position: "relative", alignItems: "center", children: [(0, jsx_runtime_1.jsx)(InputElement, { theme: theme, type: props.type ?? "checkbox", checked: checked, onChange: onChangeElement, ...styledComponentStyles, ...dataProps, ...ariaProps, ...restProps }), props.type === "checkbox" ? ((0, jsx_runtime_1.jsx)(Icon_1.default, { name: "check", position: "absolute", top: "50%", left: "50%", color: theme.colors.base, size: 14, transform: `translate(-50%, -50%)${checked ? "" : " scale(0.4)"}`, opacity: checked ? 1 : 0, pointerEvents: "none", transition: theme.styles.transition })) : props.type === "radio" ? ((0, jsx_runtime_1.jsx)(Div_1.default, { position: "absolute", width: 10, height: 10, top: "50%", left: "50%", backgroundColor: theme.colors.base, borderRadius: 999, transform: `translate(-50%, -50%)${checked ? "" : " scale(0.4)"}`, opacity: checked ? 1 : 0, pointerEvents: "none" })) : undefined] }), text && ((0, jsx_runtime_1.jsx)(Text_1.default, { userSelect: "none", cursor: "pointer", onClick: onClickText, children: text }))] }), (errorText || infoText) && ((0, jsx_runtime_1.jsx)(Text_1.default, { as: "span", display: "block", fontSize: 14, color: errorText ? theme.colors.error : theme.colors.textSecondary, children: errorText || infoText }))] }));
101
111
  });
102
112
  exports.default = {
103
113
  checkbox: (0, react_1.forwardRef)(function Checkbox(props, ref) {
@@ -106,7 +116,7 @@ exports.default = {
106
116
  radiobutton: (0, react_1.forwardRef)(function RadioButton(props, ref) {
107
117
  return (0, jsx_runtime_1.jsx)(ToggleInputComponent, { type: "radio", ref: ref, ...props });
108
118
  }),
109
- switch: (0, react_1.forwardRef)(function Switch({ label, errorText, infoText, disabled, onChange, checked: controlledChecked, required, ...props }, ref) {
119
+ switch: (0, react_1.forwardRef)(function Switch({ label, errorText, infoText, disabled, value, onChange, checked: controlledChecked, required, ...props }, ref) {
110
120
  const theme = (0, BetterHtmlProvider_1.useTheme)();
111
121
  const styledComponentStyles = (0, hooks_1.useStyledComponentStyles)(props, theme, true);
112
122
  const styledComponentStylesWithExcluded = (0, hooks_1.useComponentPropsWithExcludedStyle)(props);
@@ -114,15 +124,16 @@ exports.default = {
114
124
  const ariaProps = (0, hooks_1.useComponentPropsWithPrefix)(props, "aria");
115
125
  const restProps = (0, hooks_1.useComponentPropsWithoutStyle)(props);
116
126
  const [internalChecked, setInternalChecked] = (0, hooks_1.useBooleanState)();
127
+ const [isMouseDown, setIsMouseDown] = (0, hooks_1.useBooleanState)();
117
128
  const checked = controlledChecked ?? internalChecked;
118
129
  const onClickElement = (0, react_1.useCallback)(() => {
119
130
  if (disabled)
120
131
  return;
121
- const newValue = !checked;
132
+ const newIsChecked = !checked;
122
133
  if (controlledChecked === undefined)
123
- setInternalChecked.setState(newValue);
124
- onChange?.(newValue);
125
- }, [disabled, checked, onChange, controlledChecked]);
126
- return ((0, jsx_runtime_1.jsxs)(Div_1.default.column, { width: "100%", gap: theme.styles.gap / 2, ...styledComponentStylesWithExcluded, children: [label && ((0, jsx_runtime_1.jsxs)(Text_1.default, { as: "label", height: 16, fontSize: 14, color: errorText ? theme.colors.error : theme.colors.textSecondary, children: [label, required && ((0, jsx_runtime_1.jsxs)(Text_1.default, { as: "span", fontSize: 16, color: theme.colors.error, children: [" ", "*"] }))] })), (0, jsx_runtime_1.jsx)(Div_1.default.row, { alignItems: "center", gap: theme.styles.gap, children: (0, jsx_runtime_1.jsx)(SwitchElement, { theme: theme, checked: checked, disabled: disabled ?? false, onClick: onClickElement, ...styledComponentStyles, ...dataProps, ...ariaProps, ...restProps }) }), (errorText || infoText) && ((0, jsx_runtime_1.jsx)(Text_1.default, { as: "span", display: "block", fontSize: 14, color: errorText ? theme.colors.error : theme.colors.textSecondary, children: errorText || infoText }))] }));
134
+ setInternalChecked.setState(newIsChecked);
135
+ onChange?.(newIsChecked, value);
136
+ }, [disabled, checked, onChange, controlledChecked, value]);
137
+ return ((0, jsx_runtime_1.jsxs)(Div_1.default.column, { width: "100%", gap: theme.styles.gap / 2, ...styledComponentStylesWithExcluded, children: [label && (0, jsx_runtime_1.jsx)(Label_1.default, { text: label, required: required, isError: !!errorText }), (0, jsx_runtime_1.jsx)(Div_1.default.row, { alignItems: "center", gap: theme.styles.gap, onMouseDown: setIsMouseDown.setTrue, onMouseUp: setIsMouseDown.setFalse, onMouseOut: setIsMouseDown.setFalse, onTouchStart: setIsMouseDown.setTrue, onTouchEnd: setIsMouseDown.setFalse, onTouchCancel: setIsMouseDown.setFalse, children: (0, jsx_runtime_1.jsx)(SwitchElement, { theme: theme, checked: checked, disabled: disabled ?? false, isMouseDown: isMouseDown, onClick: onClickElement, ...styledComponentStyles, ...dataProps, ...ariaProps, ...restProps }) }), (errorText || infoText) && ((0, jsx_runtime_1.jsx)(Text_1.default, { as: "span", display: "block", fontSize: 14, color: errorText ? theme.colors.error : theme.colors.textSecondary, children: errorText || infoText }))] }));
127
138
  }),
128
139
  };
@@ -672,6 +672,7 @@ exports.countries = [
672
672
  code: "IT",
673
673
  timeZone: "Europe/Rome",
674
674
  phoneNumberExtension: "39",
675
+ phoneNumberFormat: "XXX XXX XXXX",
675
676
  },
676
677
  {
677
678
  name: "Jamaica",
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ import Label from "./components/Label";
17
17
  import FormRow from "./components/FormRow";
18
18
  import BetterHtmlProvider, { useBetterHtmlContext, useTheme, useLoader, useLoaderControls } from "./components/BetterHtmlProvider";
19
19
  import { usePageResize, usePageScroll, useMediaQuery, useBooleanState, useDebounceState, useForm, useUrlQuery } from "./utils/hooks";
20
- import { generateRandomString, getBrowser, formatPhoneNumber } from "./utils/functions";
20
+ import { generateRandomString, getBrowser, formatPhoneNumber, getFormErrorObject } from "./utils/functions";
21
21
  import { type OmitProps, type ExcludeOptions, type PickValue, type PartialRecord, type DeepPartialRecord, type PickAllRequired } from "./types/app";
22
22
  import { type AppConfig, type BetterHtmlConfig } from "./types/config";
23
23
  import { type AssetName, type AssetsConfig } from "./types/asset";
@@ -25,6 +25,7 @@ import { type IconName, type IconsConfig } from "./types/icon";
25
25
  import { type LoaderName, type LoaderConfig } from "./types/loader";
26
26
  import { type PluginName, type BetterHtmlPlugin } from "./types/plugin";
27
27
  import { type Color, type ColorName, type ColorTheme, type Colors, type Styles, type Theme, type ThemeConfig } from "./types/theme";
28
+ import { type BrowserName } from "./types/other";
28
29
  import { isMobileDevice } from "./constants";
29
30
  export * from "./plugins";
30
- export { BetterHtmlProvider, Div, Text, Loader, Icon, Image, Button, Divider, Modal, ModalRef, PageHolder, PageHeader, Chip, InputField, Dropdown, DropdownOption, ToggleInput, Form, Label, FormRow, useBetterHtmlContext, useTheme, useLoader, useLoaderControls, usePageResize, usePageScroll, useMediaQuery, useBooleanState, useDebounceState, useForm, useUrlQuery, generateRandomString, getBrowser, formatPhoneNumber, OmitProps, ExcludeOptions, PickValue, PartialRecord, DeepPartialRecord, PickAllRequired, AppConfig, BetterHtmlConfig, AssetName, AssetsConfig, IconName, IconsConfig, LoaderName, PluginName, BetterHtmlPlugin, LoaderConfig, Color, ColorName, ColorTheme, Colors, Styles, Theme, ThemeConfig, isMobileDevice, };
31
+ export { BetterHtmlProvider, Div, Text, Loader, Icon, Image, Button, Divider, Modal, ModalRef, PageHolder, PageHeader, Chip, InputField, Dropdown, DropdownOption, ToggleInput, Form, Label, FormRow, useBetterHtmlContext, useTheme, useLoader, useLoaderControls, usePageResize, usePageScroll, useMediaQuery, useBooleanState, useDebounceState, useForm, useUrlQuery, generateRandomString, getBrowser, formatPhoneNumber, getFormErrorObject, OmitProps, ExcludeOptions, PickValue, PartialRecord, DeepPartialRecord, PickAllRequired, AppConfig, BetterHtmlConfig, AssetName, AssetsConfig, IconName, IconsConfig, LoaderName, PluginName, BetterHtmlPlugin, LoaderConfig, Color, ColorName, ColorTheme, Colors, Styles, Theme, ThemeConfig, BrowserName, isMobileDevice, };
package/dist/index.js CHANGED
@@ -39,7 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
39
39
  return (mod && mod.__esModule) ? mod : { "default": mod };
40
40
  };
41
41
  Object.defineProperty(exports, "__esModule", { value: true });
42
- exports.isMobileDevice = exports.formatPhoneNumber = exports.getBrowser = exports.generateRandomString = exports.useUrlQuery = exports.useForm = exports.useDebounceState = exports.useBooleanState = exports.useMediaQuery = exports.usePageScroll = exports.usePageResize = exports.useLoaderControls = exports.useLoader = exports.useTheme = exports.useBetterHtmlContext = exports.FormRow = exports.Label = exports.Form = exports.ToggleInput = exports.Dropdown = exports.InputField = exports.Chip = exports.PageHeader = exports.PageHolder = exports.Modal = exports.Divider = exports.Button = exports.Image = exports.Icon = exports.Loader = exports.Text = exports.Div = exports.BetterHtmlProvider = void 0;
42
+ exports.isMobileDevice = exports.getFormErrorObject = exports.formatPhoneNumber = exports.getBrowser = exports.generateRandomString = exports.useUrlQuery = exports.useForm = exports.useDebounceState = exports.useBooleanState = exports.useMediaQuery = exports.usePageScroll = exports.usePageResize = exports.useLoaderControls = exports.useLoader = exports.useTheme = exports.useBetterHtmlContext = exports.FormRow = exports.Label = exports.Form = exports.ToggleInput = exports.Dropdown = exports.InputField = exports.Chip = exports.PageHeader = exports.PageHolder = exports.Modal = exports.Divider = exports.Button = exports.Image = exports.Icon = exports.Loader = exports.Text = exports.Div = exports.BetterHtmlProvider = void 0;
43
43
  const Div_1 = __importDefault(require("./components/Div"));
44
44
  exports.Div = Div_1.default;
45
45
  const Text_1 = __importDefault(require("./components/Text"));
@@ -92,6 +92,7 @@ const functions_1 = require("./utils/functions");
92
92
  Object.defineProperty(exports, "generateRandomString", { enumerable: true, get: function () { return functions_1.generateRandomString; } });
93
93
  Object.defineProperty(exports, "getBrowser", { enumerable: true, get: function () { return functions_1.getBrowser; } });
94
94
  Object.defineProperty(exports, "formatPhoneNumber", { enumerable: true, get: function () { return functions_1.formatPhoneNumber; } });
95
+ Object.defineProperty(exports, "getFormErrorObject", { enumerable: true, get: function () { return functions_1.getFormErrorObject; } });
95
96
  const constants_1 = require("./constants");
96
97
  Object.defineProperty(exports, "isMobileDevice", { enumerable: true, get: function () { return constants_1.isMobileDevice; } });
97
98
  __exportStar(require("./plugins"), exports);
@@ -0,0 +1 @@
1
+ export type BrowserName = "firefox" | "chrome" | "safari" | "edge" | "opera";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,16 @@
1
- export declare const generateRandomString: (stringLength: number) => string;
2
- export declare const getBrowser: () => "firefox" | "chrome" | "safari" | "edge" | "opera" | undefined;
1
+ import { PartialRecord } from "../types/app";
2
+ import { BrowserName } from "../types/other";
3
+ import { useForm } from "./hooks";
4
+ export declare const generateRandomString: (stringLength: number, options?: {
5
+ /** @default true */
6
+ includeCapitalLetters?: boolean;
7
+ /** @default true */
8
+ includeLowerLetters?: boolean;
9
+ /** @default true */
10
+ includeNumbers?: boolean;
11
+ /** @default 1 */
12
+ dashSections?: number;
13
+ }) => string;
14
+ export declare const getBrowser: () => BrowserName | undefined;
3
15
  export declare const formatPhoneNumber: (phoneNumber: string) => string;
16
+ export declare const getFormErrorObject: <FormFields extends ReturnType<typeof useForm>["values"]>(formValues: FormFields) => PartialRecord<keyof FormFields, string>;
@@ -1,12 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.formatPhoneNumber = exports.getBrowser = exports.generateRandomString = void 0;
3
+ exports.getFormErrorObject = exports.formatPhoneNumber = exports.getBrowser = exports.generateRandomString = void 0;
4
4
  const countries_1 = require("../constants/countries");
5
- const generateRandomString = (stringLength) => {
6
- const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
5
+ const generateRandomString = (stringLength, options) => {
6
+ const capitals = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
7
+ const lowers = "abcdefghijklmnopqrstuvwxyz";
8
+ const numbers = "0123456789";
9
+ const includes = [];
10
+ if (options?.includeCapitalLetters !== false)
11
+ includes.push(capitals);
12
+ if (options?.includeLowerLetters !== false)
13
+ includes.push(lowers);
14
+ if (options?.includeNumbers !== false)
15
+ includes.push(numbers);
16
+ const characters = includes.join("");
17
+ const dashSections = Math.max(1, options?.dashSections ?? 1);
18
+ const dashSectionLength = Math.floor(stringLength / dashSections);
19
+ if (stringLength < dashSections)
20
+ return "";
7
21
  let result = "";
8
- for (let index = 0; index < stringLength; index++) {
9
- result += characters.charAt(Math.floor(Math.random() * characters.length));
22
+ let currentSectionLength = 0;
23
+ while (result.length < stringLength) {
24
+ if (currentSectionLength >= dashSectionLength) {
25
+ result += "-";
26
+ currentSectionLength = 0;
27
+ }
28
+ if (result.length < stringLength) {
29
+ result += characters.charAt(Math.floor(Math.random() * characters.length));
30
+ currentSectionLength += 1;
31
+ }
10
32
  }
11
33
  return result;
12
34
  };
@@ -49,3 +71,7 @@ const formatPhoneNumber = (phoneNumber) => {
49
71
  return `+${country.phoneNumberExtension} ${phonNumberRest}`;
50
72
  };
51
73
  exports.formatPhoneNumber = formatPhoneNumber;
74
+ const getFormErrorObject = (formValues) => {
75
+ return {};
76
+ };
77
+ exports.getFormErrorObject = getFormErrorObject;
@@ -47,7 +47,7 @@ export declare function useBooleanState(initialValue?: boolean): [
47
47
  }
48
48
  ];
49
49
  export declare function useDebounceState<Value>(initialValue: Value, delay?: number): [value: Value, debouncedValue: Value, setValue: React.Dispatch<React.SetStateAction<Value>>, isLoading: boolean];
50
- export declare function useForm<FormFields extends Record<string, string | number | boolean | undefined>>({ defaultValues, requiredFields, onSubmit, validate, }: {
50
+ export declare function useForm<FormFields extends Record<string, string | number | boolean | undefined>>(options: {
51
51
  defaultValues: FormFields;
52
52
  requiredFields?: (keyof FormFields)[];
53
53
  onSubmit?: (values: FormFields) => void | Promise<void>;
@@ -62,6 +62,8 @@ export declare function useForm<FormFields extends Record<string, string | numbe
62
62
  getTextAreaProps: <FieldName extends keyof FormFields>(field: FieldName) => ComponentPropWithRef<HTMLTextAreaElement, TextareaFieldProps>;
63
63
  getDropdownFieldProps: <FieldName extends keyof FormFields>(field: FieldName) => OmitProps<ComponentPropWithRef<HTMLDivElement, DropdownProps<FormFields[FieldName], unknown>>, "options">;
64
64
  getCheckboxProps: <FieldName extends keyof FormFields>(field: FieldName) => ComponentPropWithRef<ToggleInputRef, ToggleInputProps<FormFields[FieldName]>>;
65
+ getRadioButtonProps: <FieldName extends keyof FormFields>(field: FieldName, value: FormFields[FieldName]) => ComponentPropWithRef<ToggleInputRef, ToggleInputProps<FormFields[FieldName]>>;
66
+ getSwitchProps: <FieldName extends keyof FormFields>(field: FieldName) => ComponentPropWithRef<ToggleInputRef, ToggleInputProps<FormFields[FieldName]>>;
65
67
  focusField: (field: keyof FormFields) => void;
66
68
  onSubmit: (event: React.FormEvent<HTMLFormElement>) => Promise<void>;
67
69
  reset: () => void;
@@ -175,7 +175,8 @@ function useDebounceState(initialValue, delay = 0.5) {
175
175
  }, [value, delay]);
176
176
  return [value, debouncedValue, setValue, isLoading];
177
177
  }
178
- function useForm({ defaultValues, requiredFields, onSubmit, validate, }) {
178
+ function useForm(options) {
179
+ const { defaultValues, requiredFields, onSubmit, validate } = options;
179
180
  const inputFieldRefs = (0, react_1.useRef)({});
180
181
  const [inputTypes, setInputTypes] = (0, react_1.useState)({});
181
182
  const [values, setValues] = (0, react_1.useState)(defaultValues);
@@ -255,6 +256,28 @@ function useForm({ defaultValues, requiredFields, onSubmit, validate, }) {
255
256
  errorText: errors[field],
256
257
  };
257
258
  }, [values, errors, setFieldValue]);
259
+ const getRadioButtonProps = (0, react_1.useCallback)((field, value) => {
260
+ return {
261
+ required: requiredFields?.includes(field),
262
+ checked: values[field] === value,
263
+ name: field.toString(),
264
+ value,
265
+ onChange: (checked, newValue) => {
266
+ setFieldValue(field, checked ? newValue : undefined);
267
+ },
268
+ errorText: errors[field],
269
+ };
270
+ }, [values, errors, setFieldValue]);
271
+ const getSwitchProps = (0, react_1.useCallback)((field) => {
272
+ return {
273
+ required: requiredFields?.includes(field),
274
+ checked: values[field],
275
+ onChange: (checked) => {
276
+ setFieldValue(field, checked);
277
+ },
278
+ errorText: errors[field],
279
+ };
280
+ }, [values, errors, setFieldValue]);
258
281
  const focusField = (0, react_1.useCallback)((field) => {
259
282
  inputFieldRefs.current[field]?.focus();
260
283
  }, []);
@@ -290,6 +313,8 @@ function useForm({ defaultValues, requiredFields, onSubmit, validate, }) {
290
313
  getTextAreaProps,
291
314
  getDropdownFieldProps,
292
315
  getCheckboxProps,
316
+ getRadioButtonProps,
317
+ getSwitchProps,
293
318
  focusField,
294
319
  onSubmit: onSubmitFunction,
295
320
  reset,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-better-html",
3
- "version": "1.1.43",
3
+ "version": "1.1.45",
4
4
  "description": "A component library for react that is as close to plane html as possible",
5
5
  "main": "dist/index.js",
6
6
  "files": [