elseware-ui 3.0.6 → 3.0.7
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/LICENSE +20 -20
- package/dist/index.css +60 -144
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +9 -39
- package/dist/index.d.ts +9 -39
- package/dist/index.js +860 -359
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +856 -355
- package/dist/index.mjs.map +1 -1
- package/dist/index.native.d.mts +13 -3
- package/dist/index.native.d.ts +13 -3
- package/dist/index.native.js +1009 -212
- package/dist/index.native.js.map +1 -1
- package/dist/index.native.mjs +1006 -214
- package/dist/index.native.mjs.map +1 -1
- package/dist/{resolveGlobalConfigs-PbcnVEZr.d.mts → resolveGlobalConfigs-C0BREpe1.d.mts} +93 -1
- package/dist/{resolveGlobalConfigs-PbcnVEZr.d.ts → resolveGlobalConfigs-C0BREpe1.d.ts} +93 -1
- package/package.json +1 -1
package/dist/index.native.js
CHANGED
|
@@ -600,139 +600,6 @@ function Checkbox(checkboxProps) {
|
|
|
600
600
|
errorText ? /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.Text, { className: "px-2 py-1 text-sm font-medium text-eui-danger-500", children: errorText }) : null
|
|
601
601
|
] });
|
|
602
602
|
}
|
|
603
|
-
function renderFormChildren(children, formik) {
|
|
604
|
-
return typeof children === "function" ? children(formik) : children;
|
|
605
|
-
}
|
|
606
|
-
function FormObservers({
|
|
607
|
-
formik,
|
|
608
|
-
onChange,
|
|
609
|
-
onDirtyChange
|
|
610
|
-
}) {
|
|
611
|
-
const prevValuesRef = react.useRef(formik.values);
|
|
612
|
-
react.useEffect(() => {
|
|
613
|
-
onDirtyChange?.(formik.dirty);
|
|
614
|
-
}, [formik.dirty, onDirtyChange]);
|
|
615
|
-
react.useEffect(() => {
|
|
616
|
-
if (!onChange) return;
|
|
617
|
-
const currentValues = formik.values;
|
|
618
|
-
const prevValues = prevValuesRef.current;
|
|
619
|
-
const changed = {};
|
|
620
|
-
Object.keys(currentValues).forEach((key) => {
|
|
621
|
-
if (currentValues[key] !== prevValues[key]) {
|
|
622
|
-
changed[key] = currentValues[key];
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
if (Object.keys(changed).length > 0) {
|
|
626
|
-
onChange(currentValues, { changed });
|
|
627
|
-
}
|
|
628
|
-
prevValuesRef.current = currentValues;
|
|
629
|
-
}, [formik.values, onChange]);
|
|
630
|
-
return null;
|
|
631
|
-
}
|
|
632
|
-
function Form({
|
|
633
|
-
initialValues = {},
|
|
634
|
-
validationSchema,
|
|
635
|
-
enableReinitialize,
|
|
636
|
-
children,
|
|
637
|
-
className,
|
|
638
|
-
contentClassName,
|
|
639
|
-
onSubmit,
|
|
640
|
-
onChange,
|
|
641
|
-
onDirtyChange
|
|
642
|
-
}) {
|
|
643
|
-
return /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
644
|
-
formik.Formik,
|
|
645
|
-
{
|
|
646
|
-
initialValues,
|
|
647
|
-
validationSchema,
|
|
648
|
-
enableReinitialize,
|
|
649
|
-
onSubmit: async (values, helpers) => {
|
|
650
|
-
await onSubmit(values, helpers);
|
|
651
|
-
},
|
|
652
|
-
children: (formik) => /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: cn(className), children: [
|
|
653
|
-
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
654
|
-
FormObservers,
|
|
655
|
-
{
|
|
656
|
-
formik,
|
|
657
|
-
onChange,
|
|
658
|
-
onDirtyChange
|
|
659
|
-
}
|
|
660
|
-
),
|
|
661
|
-
/* @__PURE__ */ jsxRuntime$1.jsx(reactNative.View, { className: cn(contentClassName), children: renderFormChildren(children, formik) })
|
|
662
|
-
] })
|
|
663
|
-
}
|
|
664
|
-
);
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// src/components/data-entry/form/form-response/base/FormResponse.styles.ts
|
|
668
|
-
var formResponseSizeStyles = {
|
|
669
|
-
xs: {
|
|
670
|
-
root: "px-2 py-1",
|
|
671
|
-
text: "text-xs"
|
|
672
|
-
},
|
|
673
|
-
sm: {
|
|
674
|
-
root: "px-3 py-2",
|
|
675
|
-
text: "text-sm"
|
|
676
|
-
},
|
|
677
|
-
md: {
|
|
678
|
-
root: "px-4 py-2",
|
|
679
|
-
text: "text-base"
|
|
680
|
-
},
|
|
681
|
-
lg: {
|
|
682
|
-
root: "px-5 py-3",
|
|
683
|
-
text: "text-lg"
|
|
684
|
-
},
|
|
685
|
-
xl: {
|
|
686
|
-
root: "px-6 py-4",
|
|
687
|
-
text: "text-xl"
|
|
688
|
-
}
|
|
689
|
-
};
|
|
690
|
-
function isTextClassName(token) {
|
|
691
|
-
const styleToken = token.split(":").pop() ?? token;
|
|
692
|
-
return styleToken.startsWith("text-");
|
|
693
|
-
}
|
|
694
|
-
function splitClassName(className) {
|
|
695
|
-
const tokens = className.split(/\s+/).filter(Boolean);
|
|
696
|
-
return {
|
|
697
|
-
root: tokens.filter((token) => !isTextClassName(token)).join(" "),
|
|
698
|
-
text: tokens.filter(isTextClassName).join(" ")
|
|
699
|
-
};
|
|
700
|
-
}
|
|
701
|
-
function resolveFormResponseStyles({
|
|
702
|
-
shape,
|
|
703
|
-
size,
|
|
704
|
-
variant
|
|
705
|
-
}) {
|
|
706
|
-
const variantClassNames = splitClassName(variantsLite[variant]);
|
|
707
|
-
const sizeClassNames = formResponseSizeStyles[size];
|
|
708
|
-
return {
|
|
709
|
-
rootClassName: [
|
|
710
|
-
"border",
|
|
711
|
-
variantClassNames.root,
|
|
712
|
-
shapes[shape],
|
|
713
|
-
sizeClassNames.root
|
|
714
|
-
].filter(Boolean).join(" "),
|
|
715
|
-
textClassName: [
|
|
716
|
-
"font-poppins font-light",
|
|
717
|
-
variantClassNames.text,
|
|
718
|
-
sizeClassNames.text
|
|
719
|
-
].filter(Boolean).join(" ")
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
function FormResponse({
|
|
723
|
-
text,
|
|
724
|
-
variant = "default",
|
|
725
|
-
shape = "roundedSquare",
|
|
726
|
-
size = "md",
|
|
727
|
-
className,
|
|
728
|
-
textClassName
|
|
729
|
-
}) {
|
|
730
|
-
if (!text) {
|
|
731
|
-
return null;
|
|
732
|
-
}
|
|
733
|
-
const styles = resolveFormResponseStyles({ shape, size, variant });
|
|
734
|
-
return /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.View, { className: cn(styles.rootClassName, className), children: /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.Text, { className: cn(styles.textClassName, textClassName), children: text }) });
|
|
735
|
-
}
|
|
736
603
|
|
|
737
604
|
// src/components/data-entry/input/input-label/base/InputLabel.styles.ts
|
|
738
605
|
var inputLabelStaticClassName = "pointer-events-none select-none px-0 text-[13.5px] leading-none text-[#6B7280]";
|
|
@@ -876,35 +743,8 @@ function InputResponse({
|
|
|
876
743
|
}
|
|
877
744
|
) });
|
|
878
745
|
}
|
|
879
|
-
function resolveInputType({
|
|
880
|
-
passwordVisible,
|
|
881
|
-
type
|
|
882
|
-
}) {
|
|
883
|
-
return type === "password" && passwordVisible ? "text" : type;
|
|
884
|
-
}
|
|
885
|
-
function useResolvedInputConfig({
|
|
886
|
-
label,
|
|
887
|
-
placeholder,
|
|
888
|
-
shape,
|
|
889
|
-
type = "text"
|
|
890
|
-
}) {
|
|
891
|
-
const eui = useEUIConfig();
|
|
892
|
-
return {
|
|
893
|
-
shape: shape ?? eui?.config?.global?.shape ?? "square",
|
|
894
|
-
type,
|
|
895
|
-
label: label ?? placeholder
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
function useInputFieldState(props) {
|
|
899
|
-
const [field, meta, helpers] = formik.useField(props);
|
|
900
|
-
return {
|
|
901
|
-
field,
|
|
902
|
-
meta,
|
|
903
|
-
helpers
|
|
904
|
-
};
|
|
905
|
-
}
|
|
906
746
|
|
|
907
|
-
// src/
|
|
747
|
+
// src/data/styles/shared.styles.tsx
|
|
908
748
|
var inputShapes = shapes;
|
|
909
749
|
var inputRootClassName = "relative w-full";
|
|
910
750
|
var inputFrameClassName = "relative h-14 w-full overflow-hidden border bg-white/95 px-3 dark:bg-eui-primary-300/10";
|
|
@@ -929,55 +769,49 @@ var nativeInputControlStyle = {
|
|
|
929
769
|
outlineStyle: "none",
|
|
930
770
|
textAlignVertical: "center"
|
|
931
771
|
};
|
|
932
|
-
function
|
|
772
|
+
function useResolvedDateSelectorConfig({
|
|
773
|
+
label,
|
|
774
|
+
placeholder,
|
|
775
|
+
shape
|
|
776
|
+
}) {
|
|
777
|
+
const eui = useEUIConfig();
|
|
778
|
+
return {
|
|
779
|
+
label: label ?? placeholder,
|
|
780
|
+
shape: shape ?? eui?.config?.global?.shape ?? "square"
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
function useDateSelectorFieldState(props) {
|
|
784
|
+
const [field, meta, helpers] = formik.useField(props);
|
|
785
|
+
return {
|
|
786
|
+
field,
|
|
787
|
+
helpers,
|
|
788
|
+
meta
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
function DateSelector(dateSelectorProps) {
|
|
933
792
|
const {
|
|
934
|
-
|
|
935
|
-
label,
|
|
936
|
-
placeholder,
|
|
793
|
+
disabled = false,
|
|
937
794
|
inputClassName,
|
|
795
|
+
label,
|
|
938
796
|
labelClassName,
|
|
797
|
+
placeholder,
|
|
939
798
|
responseClassName,
|
|
940
|
-
step: _step,
|
|
941
799
|
shape,
|
|
942
|
-
|
|
800
|
+
styles,
|
|
943
801
|
className,
|
|
944
802
|
onBlur,
|
|
945
|
-
onFocus
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
} = inputProps;
|
|
949
|
-
const { field, helpers, meta } = useInputFieldState(inputProps);
|
|
803
|
+
onFocus
|
|
804
|
+
} = dateSelectorProps;
|
|
805
|
+
const { field, helpers, meta } = useDateSelectorFieldState(dateSelectorProps);
|
|
950
806
|
const [focused, setFocused] = react.useState(false);
|
|
951
|
-
const
|
|
952
|
-
const
|
|
953
|
-
new reactNative.Animated.Value(String(field.value ?? "").length > 0 ? 1 : 0)
|
|
954
|
-
).current;
|
|
955
|
-
const {
|
|
956
|
-
shape: resolvedShape,
|
|
957
|
-
type: resolvedType,
|
|
958
|
-
label: resolvedLabel
|
|
959
|
-
} = useResolvedInputConfig({
|
|
807
|
+
const labelProgress = react.useRef(new reactNative.Animated.Value(1)).current;
|
|
808
|
+
const { label: resolvedLabel, shape: resolvedShape } = useResolvedDateSelectorConfig({
|
|
960
809
|
label,
|
|
961
810
|
placeholder,
|
|
962
|
-
shape
|
|
963
|
-
type
|
|
964
|
-
});
|
|
965
|
-
const inputType = resolveInputType({
|
|
966
|
-
passwordVisible,
|
|
967
|
-
type: resolvedType
|
|
811
|
+
shape
|
|
968
812
|
});
|
|
969
813
|
const hasError = Boolean(meta.touched && meta.error);
|
|
970
814
|
const errorText = hasError && typeof meta.error === "string" ? meta.error : null;
|
|
971
|
-
const hasValue = String(field.value ?? "").length > 0;
|
|
972
|
-
const floating = focused || hasValue;
|
|
973
|
-
react.useEffect(() => {
|
|
974
|
-
reactNative.Animated.timing(labelProgress, {
|
|
975
|
-
duration: 190,
|
|
976
|
-
easing: reactNative.Easing.out(reactNative.Easing.cubic),
|
|
977
|
-
toValue: floating ? 1 : 0,
|
|
978
|
-
useNativeDriver: false
|
|
979
|
-
}).start();
|
|
980
|
-
}, [floating, labelProgress]);
|
|
981
815
|
const handleBlur = (event) => {
|
|
982
816
|
setFocused(false);
|
|
983
817
|
helpers.setTouched(true);
|
|
@@ -985,7 +819,9 @@ function Input(inputProps) {
|
|
|
985
819
|
};
|
|
986
820
|
const handleFocus = (event) => {
|
|
987
821
|
setFocused(true);
|
|
988
|
-
onFocus?.(
|
|
822
|
+
onFocus?.(
|
|
823
|
+
event
|
|
824
|
+
);
|
|
989
825
|
};
|
|
990
826
|
return /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: inputRootClassName, children: [
|
|
991
827
|
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
@@ -996,7 +832,8 @@ function Input(inputProps) {
|
|
|
996
832
|
hasError ? inputFrameErrorClassName : focused ? inputFrameActiveClassName : inputFrameIdleClassName,
|
|
997
833
|
inputShapes[resolvedShape],
|
|
998
834
|
disabled && inputFrameDisabledClassName,
|
|
999
|
-
className
|
|
835
|
+
className,
|
|
836
|
+
styles
|
|
1000
837
|
),
|
|
1001
838
|
children: /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1002
839
|
reactNative.TextInput,
|
|
@@ -1005,16 +842,14 @@ function Input(inputProps) {
|
|
|
1005
842
|
className: cn(
|
|
1006
843
|
inputControlClassName,
|
|
1007
844
|
nativeInputControlClassName,
|
|
1008
|
-
type === "password" && nativePasswordInputClassName,
|
|
1009
845
|
inputClassName
|
|
1010
846
|
),
|
|
1011
847
|
editable: !disabled,
|
|
1012
|
-
keyboardType:
|
|
848
|
+
keyboardType: "numbers-and-punctuation",
|
|
1013
849
|
onBlur: handleBlur,
|
|
1014
850
|
onChangeText: (value) => helpers.setValue(value),
|
|
1015
851
|
onFocus: handleFocus,
|
|
1016
852
|
placeholder: "",
|
|
1017
|
-
secureTextEntry: type === "password" && !passwordVisible,
|
|
1018
853
|
style: nativeInputControlStyle,
|
|
1019
854
|
underlineColorAndroid: "transparent",
|
|
1020
855
|
value: field.value ?? ""
|
|
@@ -1028,22 +863,979 @@ function Input(inputProps) {
|
|
|
1028
863
|
animatedValue: labelProgress,
|
|
1029
864
|
disabled,
|
|
1030
865
|
errored: hasError,
|
|
1031
|
-
floating,
|
|
866
|
+
floating: true,
|
|
1032
867
|
text: resolvedLabel,
|
|
1033
868
|
className: labelClassName
|
|
1034
869
|
}
|
|
1035
870
|
),
|
|
1036
|
-
|
|
1037
|
-
|
|
871
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
872
|
+
InputResponse,
|
|
1038
873
|
{
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
children: /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.Text, { className: nativePasswordToggleTextClassName, children: passwordVisible ? "Hide" : "Show" })
|
|
874
|
+
message: errorText,
|
|
875
|
+
name: field.name,
|
|
876
|
+
visibility: Boolean(errorText),
|
|
877
|
+
variant: "danger",
|
|
878
|
+
className: responseClassName
|
|
1045
879
|
}
|
|
1046
|
-
)
|
|
880
|
+
)
|
|
881
|
+
] });
|
|
882
|
+
}
|
|
883
|
+
function renderFormChildren(children, formik) {
|
|
884
|
+
return typeof children === "function" ? children(formik) : children;
|
|
885
|
+
}
|
|
886
|
+
function FormObservers({
|
|
887
|
+
formik,
|
|
888
|
+
onChange,
|
|
889
|
+
onDirtyChange
|
|
890
|
+
}) {
|
|
891
|
+
const prevValuesRef = react.useRef(formik.values);
|
|
892
|
+
react.useEffect(() => {
|
|
893
|
+
onDirtyChange?.(formik.dirty);
|
|
894
|
+
}, [formik.dirty, onDirtyChange]);
|
|
895
|
+
react.useEffect(() => {
|
|
896
|
+
if (!onChange) return;
|
|
897
|
+
const currentValues = formik.values;
|
|
898
|
+
const prevValues = prevValuesRef.current;
|
|
899
|
+
const changed = {};
|
|
900
|
+
Object.keys(currentValues).forEach((key) => {
|
|
901
|
+
if (currentValues[key] !== prevValues[key]) {
|
|
902
|
+
changed[key] = currentValues[key];
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
if (Object.keys(changed).length > 0) {
|
|
906
|
+
onChange(currentValues, { changed });
|
|
907
|
+
}
|
|
908
|
+
prevValuesRef.current = currentValues;
|
|
909
|
+
}, [formik.values, onChange]);
|
|
910
|
+
return null;
|
|
911
|
+
}
|
|
912
|
+
function Form({
|
|
913
|
+
initialValues = {},
|
|
914
|
+
validationSchema,
|
|
915
|
+
enableReinitialize,
|
|
916
|
+
children,
|
|
917
|
+
className,
|
|
918
|
+
contentClassName,
|
|
919
|
+
onSubmit,
|
|
920
|
+
onChange,
|
|
921
|
+
onDirtyChange
|
|
922
|
+
}) {
|
|
923
|
+
return /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
924
|
+
formik.Formik,
|
|
925
|
+
{
|
|
926
|
+
initialValues,
|
|
927
|
+
validationSchema,
|
|
928
|
+
enableReinitialize,
|
|
929
|
+
onSubmit: async (values, helpers) => {
|
|
930
|
+
await onSubmit(values, helpers);
|
|
931
|
+
},
|
|
932
|
+
children: (formik) => /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: cn(className), children: [
|
|
933
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
934
|
+
FormObservers,
|
|
935
|
+
{
|
|
936
|
+
formik,
|
|
937
|
+
onChange,
|
|
938
|
+
onDirtyChange
|
|
939
|
+
}
|
|
940
|
+
),
|
|
941
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(reactNative.View, { className: cn(contentClassName), children: renderFormChildren(children, formik) })
|
|
942
|
+
] })
|
|
943
|
+
}
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// src/components/data-entry/form/form-response/base/FormResponse.styles.ts
|
|
948
|
+
var formResponseSizeStyles = {
|
|
949
|
+
xs: {
|
|
950
|
+
root: "px-2 py-1",
|
|
951
|
+
text: "text-xs"
|
|
952
|
+
},
|
|
953
|
+
sm: {
|
|
954
|
+
root: "px-3 py-2",
|
|
955
|
+
text: "text-sm"
|
|
956
|
+
},
|
|
957
|
+
md: {
|
|
958
|
+
root: "px-4 py-2",
|
|
959
|
+
text: "text-base"
|
|
960
|
+
},
|
|
961
|
+
lg: {
|
|
962
|
+
root: "px-5 py-3",
|
|
963
|
+
text: "text-lg"
|
|
964
|
+
},
|
|
965
|
+
xl: {
|
|
966
|
+
root: "px-6 py-4",
|
|
967
|
+
text: "text-xl"
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
function isTextClassName(token) {
|
|
971
|
+
const styleToken = token.split(":").pop() ?? token;
|
|
972
|
+
return styleToken.startsWith("text-");
|
|
973
|
+
}
|
|
974
|
+
function splitClassName(className) {
|
|
975
|
+
const tokens = className.split(/\s+/).filter(Boolean);
|
|
976
|
+
return {
|
|
977
|
+
root: tokens.filter((token) => !isTextClassName(token)).join(" "),
|
|
978
|
+
text: tokens.filter(isTextClassName).join(" ")
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
function resolveFormResponseStyles({
|
|
982
|
+
shape,
|
|
983
|
+
size,
|
|
984
|
+
variant
|
|
985
|
+
}) {
|
|
986
|
+
const variantClassNames = splitClassName(variantsLite[variant]);
|
|
987
|
+
const sizeClassNames = formResponseSizeStyles[size];
|
|
988
|
+
return {
|
|
989
|
+
rootClassName: [
|
|
990
|
+
"border",
|
|
991
|
+
variantClassNames.root,
|
|
992
|
+
shapes[shape],
|
|
993
|
+
sizeClassNames.root
|
|
994
|
+
].filter(Boolean).join(" "),
|
|
995
|
+
textClassName: [
|
|
996
|
+
"font-poppins font-light",
|
|
997
|
+
variantClassNames.text,
|
|
998
|
+
sizeClassNames.text
|
|
999
|
+
].filter(Boolean).join(" ")
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
function FormResponse({
|
|
1003
|
+
text,
|
|
1004
|
+
variant = "default",
|
|
1005
|
+
shape = "roundedSquare",
|
|
1006
|
+
size = "md",
|
|
1007
|
+
className,
|
|
1008
|
+
textClassName
|
|
1009
|
+
}) {
|
|
1010
|
+
if (!text) {
|
|
1011
|
+
return null;
|
|
1012
|
+
}
|
|
1013
|
+
const styles = resolveFormResponseStyles({ shape, size, variant });
|
|
1014
|
+
return /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.View, { className: cn(styles.rootClassName, className), children: /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.Text, { className: cn(styles.textClassName, textClassName), children: text }) });
|
|
1015
|
+
}
|
|
1016
|
+
function resolveInputType({
|
|
1017
|
+
passwordVisible,
|
|
1018
|
+
type
|
|
1019
|
+
}) {
|
|
1020
|
+
return type === "password" && passwordVisible ? "text" : type;
|
|
1021
|
+
}
|
|
1022
|
+
function useResolvedInputConfig({
|
|
1023
|
+
label,
|
|
1024
|
+
placeholder,
|
|
1025
|
+
shape,
|
|
1026
|
+
type = "text"
|
|
1027
|
+
}) {
|
|
1028
|
+
const eui = useEUIConfig();
|
|
1029
|
+
return {
|
|
1030
|
+
shape: shape ?? eui?.config?.global?.shape ?? "square",
|
|
1031
|
+
type,
|
|
1032
|
+
label: label ?? placeholder
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
function useInputFieldState(props) {
|
|
1036
|
+
const [field, meta, helpers] = formik.useField(props);
|
|
1037
|
+
return {
|
|
1038
|
+
field,
|
|
1039
|
+
meta,
|
|
1040
|
+
helpers
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
function Input(inputProps) {
|
|
1044
|
+
const {
|
|
1045
|
+
type = "text",
|
|
1046
|
+
label,
|
|
1047
|
+
placeholder,
|
|
1048
|
+
inputClassName,
|
|
1049
|
+
labelClassName,
|
|
1050
|
+
responseClassName,
|
|
1051
|
+
step: _step,
|
|
1052
|
+
shape,
|
|
1053
|
+
disabled = false,
|
|
1054
|
+
className,
|
|
1055
|
+
onBlur,
|
|
1056
|
+
onFocus,
|
|
1057
|
+
onChange: _onChange,
|
|
1058
|
+
..._props
|
|
1059
|
+
} = inputProps;
|
|
1060
|
+
const { field, helpers, meta } = useInputFieldState(inputProps);
|
|
1061
|
+
const [focused, setFocused] = react.useState(false);
|
|
1062
|
+
const [passwordVisible, setPasswordVisible] = react.useState(false);
|
|
1063
|
+
const labelProgress = react.useRef(
|
|
1064
|
+
new reactNative.Animated.Value(String(field.value ?? "").length > 0 ? 1 : 0)
|
|
1065
|
+
).current;
|
|
1066
|
+
const {
|
|
1067
|
+
shape: resolvedShape,
|
|
1068
|
+
type: resolvedType,
|
|
1069
|
+
label: resolvedLabel
|
|
1070
|
+
} = useResolvedInputConfig({
|
|
1071
|
+
label,
|
|
1072
|
+
placeholder,
|
|
1073
|
+
shape,
|
|
1074
|
+
type
|
|
1075
|
+
});
|
|
1076
|
+
const inputType = resolveInputType({
|
|
1077
|
+
passwordVisible,
|
|
1078
|
+
type: resolvedType
|
|
1079
|
+
});
|
|
1080
|
+
const hasError = Boolean(meta.touched && meta.error);
|
|
1081
|
+
const errorText = hasError && typeof meta.error === "string" ? meta.error : null;
|
|
1082
|
+
const hasValue = String(field.value ?? "").length > 0;
|
|
1083
|
+
const floating = focused || hasValue;
|
|
1084
|
+
react.useEffect(() => {
|
|
1085
|
+
reactNative.Animated.timing(labelProgress, {
|
|
1086
|
+
duration: 190,
|
|
1087
|
+
easing: reactNative.Easing.out(reactNative.Easing.cubic),
|
|
1088
|
+
toValue: floating ? 1 : 0,
|
|
1089
|
+
useNativeDriver: false
|
|
1090
|
+
}).start();
|
|
1091
|
+
}, [floating, labelProgress]);
|
|
1092
|
+
const handleBlur = (event) => {
|
|
1093
|
+
setFocused(false);
|
|
1094
|
+
helpers.setTouched(true);
|
|
1095
|
+
onBlur?.(event);
|
|
1096
|
+
};
|
|
1097
|
+
const handleFocus = (event) => {
|
|
1098
|
+
setFocused(true);
|
|
1099
|
+
onFocus?.(event);
|
|
1100
|
+
};
|
|
1101
|
+
return /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: inputRootClassName, children: [
|
|
1102
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1103
|
+
reactNative.View,
|
|
1104
|
+
{
|
|
1105
|
+
className: cn(
|
|
1106
|
+
inputFrameClassName,
|
|
1107
|
+
hasError ? inputFrameErrorClassName : focused ? inputFrameActiveClassName : inputFrameIdleClassName,
|
|
1108
|
+
inputShapes[resolvedShape],
|
|
1109
|
+
disabled && inputFrameDisabledClassName,
|
|
1110
|
+
className
|
|
1111
|
+
),
|
|
1112
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1113
|
+
reactNative.TextInput,
|
|
1114
|
+
{
|
|
1115
|
+
accessibilityLabel: resolvedLabel,
|
|
1116
|
+
className: cn(
|
|
1117
|
+
inputControlClassName,
|
|
1118
|
+
nativeInputControlClassName,
|
|
1119
|
+
type === "password" && nativePasswordInputClassName,
|
|
1120
|
+
inputClassName
|
|
1121
|
+
),
|
|
1122
|
+
editable: !disabled,
|
|
1123
|
+
keyboardType: inputType === "number" ? "numeric" : "default",
|
|
1124
|
+
onBlur: handleBlur,
|
|
1125
|
+
onChangeText: (value) => helpers.setValue(value),
|
|
1126
|
+
onFocus: handleFocus,
|
|
1127
|
+
placeholder: "",
|
|
1128
|
+
secureTextEntry: type === "password" && !passwordVisible,
|
|
1129
|
+
style: nativeInputControlStyle,
|
|
1130
|
+
underlineColorAndroid: "transparent",
|
|
1131
|
+
value: field.value ?? ""
|
|
1132
|
+
}
|
|
1133
|
+
)
|
|
1134
|
+
}
|
|
1135
|
+
),
|
|
1136
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1137
|
+
InputLabel,
|
|
1138
|
+
{
|
|
1139
|
+
animatedValue: labelProgress,
|
|
1140
|
+
disabled,
|
|
1141
|
+
errored: hasError,
|
|
1142
|
+
floating,
|
|
1143
|
+
text: resolvedLabel,
|
|
1144
|
+
className: labelClassName
|
|
1145
|
+
}
|
|
1146
|
+
),
|
|
1147
|
+
type === "password" ? /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1148
|
+
reactNative.Pressable,
|
|
1149
|
+
{
|
|
1150
|
+
accessibilityRole: "button",
|
|
1151
|
+
accessibilityLabel: passwordVisible ? "Hide password" : "Show password",
|
|
1152
|
+
className: nativePasswordToggleClassName,
|
|
1153
|
+
disabled,
|
|
1154
|
+
onPress: () => setPasswordVisible((current) => !current),
|
|
1155
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.Text, { className: nativePasswordToggleTextClassName, children: passwordVisible ? "Hide" : "Show" })
|
|
1156
|
+
}
|
|
1157
|
+
) : null,
|
|
1158
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1159
|
+
InputResponse,
|
|
1160
|
+
{
|
|
1161
|
+
message: errorText,
|
|
1162
|
+
name: field.name,
|
|
1163
|
+
visibility: Boolean(errorText),
|
|
1164
|
+
variant: "danger",
|
|
1165
|
+
className: responseClassName
|
|
1166
|
+
}
|
|
1167
|
+
)
|
|
1168
|
+
] });
|
|
1169
|
+
}
|
|
1170
|
+
function useResolvedInputFileConfig({
|
|
1171
|
+
label,
|
|
1172
|
+
placeholder,
|
|
1173
|
+
shape
|
|
1174
|
+
}) {
|
|
1175
|
+
const eui = useEUIConfig();
|
|
1176
|
+
return {
|
|
1177
|
+
label: label ?? placeholder,
|
|
1178
|
+
shape: shape ?? eui?.config?.global?.shape ?? "square"
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
function useInputFileFieldState(props) {
|
|
1182
|
+
const [field, meta, helpers] = formik.useField(props);
|
|
1183
|
+
return {
|
|
1184
|
+
field,
|
|
1185
|
+
helpers,
|
|
1186
|
+
meta
|
|
1187
|
+
};
|
|
1188
|
+
}
|
|
1189
|
+
function isNativeInputFileValue(file) {
|
|
1190
|
+
return Boolean(file && typeof file === "object");
|
|
1191
|
+
}
|
|
1192
|
+
function getInputFileName(file) {
|
|
1193
|
+
if (!isNativeInputFileValue(file)) {
|
|
1194
|
+
return "";
|
|
1195
|
+
}
|
|
1196
|
+
if ("name" in file && file.name) {
|
|
1197
|
+
return file.name;
|
|
1198
|
+
}
|
|
1199
|
+
if ("fileName" in file && file.fileName) {
|
|
1200
|
+
return file.fileName;
|
|
1201
|
+
}
|
|
1202
|
+
if ("uri" in file && file.uri) {
|
|
1203
|
+
return file.uri.split("/").filter(Boolean).pop() ?? "";
|
|
1204
|
+
}
|
|
1205
|
+
return "";
|
|
1206
|
+
}
|
|
1207
|
+
function InputFile(inputFileProps) {
|
|
1208
|
+
const {
|
|
1209
|
+
disabled = false,
|
|
1210
|
+
inputClassName,
|
|
1211
|
+
label,
|
|
1212
|
+
labelClassName,
|
|
1213
|
+
onFileSelect,
|
|
1214
|
+
placeholder,
|
|
1215
|
+
responseClassName,
|
|
1216
|
+
shape,
|
|
1217
|
+
className
|
|
1218
|
+
} = inputFileProps;
|
|
1219
|
+
const { field, meta, helpers } = useInputFileFieldState(inputFileProps);
|
|
1220
|
+
const [focused, setFocused] = react.useState(false);
|
|
1221
|
+
const { label: resolvedLabel, shape: resolvedShape } = useResolvedInputFileConfig({
|
|
1222
|
+
label,
|
|
1223
|
+
placeholder,
|
|
1224
|
+
shape
|
|
1225
|
+
});
|
|
1226
|
+
const hasError = Boolean(meta.touched && meta.error);
|
|
1227
|
+
const errorText = hasError && typeof meta.error === "string" ? meta.error : null;
|
|
1228
|
+
const fileName = getInputFileName(field.value);
|
|
1229
|
+
const floating = focused || Boolean(fileName);
|
|
1230
|
+
const handlePress = async () => {
|
|
1231
|
+
if (disabled || !onFileSelect) {
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
setFocused(true);
|
|
1235
|
+
const selectedFile = await onFileSelect();
|
|
1236
|
+
if (selectedFile !== void 0) {
|
|
1237
|
+
await helpers.setValue(selectedFile);
|
|
1238
|
+
await helpers.setTouched(true);
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1241
|
+
return /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: inputRootClassName, children: [
|
|
1242
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1243
|
+
reactNative.Pressable,
|
|
1244
|
+
{
|
|
1245
|
+
accessibilityLabel: resolvedLabel,
|
|
1246
|
+
accessibilityRole: "button",
|
|
1247
|
+
disabled,
|
|
1248
|
+
onBlur: () => setFocused(false),
|
|
1249
|
+
onFocus: () => setFocused(true),
|
|
1250
|
+
onPress: () => void handlePress(),
|
|
1251
|
+
className: cn(
|
|
1252
|
+
inputFrameClassName,
|
|
1253
|
+
"justify-center",
|
|
1254
|
+
hasError ? inputFrameErrorClassName : focused ? inputFrameActiveClassName : inputFrameIdleClassName,
|
|
1255
|
+
inputShapes[resolvedShape],
|
|
1256
|
+
disabled && inputFrameDisabledClassName,
|
|
1257
|
+
className
|
|
1258
|
+
),
|
|
1259
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1260
|
+
reactNative.Text,
|
|
1261
|
+
{
|
|
1262
|
+
numberOfLines: 1,
|
|
1263
|
+
className: cn(
|
|
1264
|
+
inputControlClassName,
|
|
1265
|
+
"pt-5 pb-2",
|
|
1266
|
+
!fileName && "text-gray-500 dark:text-gray-300",
|
|
1267
|
+
inputClassName
|
|
1268
|
+
),
|
|
1269
|
+
style: { includeFontPadding: false },
|
|
1270
|
+
children: fileName
|
|
1271
|
+
}
|
|
1272
|
+
)
|
|
1273
|
+
}
|
|
1274
|
+
),
|
|
1275
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1276
|
+
InputLabel,
|
|
1277
|
+
{
|
|
1278
|
+
disabled,
|
|
1279
|
+
errored: hasError,
|
|
1280
|
+
floating,
|
|
1281
|
+
text: resolvedLabel,
|
|
1282
|
+
className: labelClassName
|
|
1283
|
+
}
|
|
1284
|
+
),
|
|
1285
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1286
|
+
InputResponse,
|
|
1287
|
+
{
|
|
1288
|
+
message: errorText,
|
|
1289
|
+
name: field.name,
|
|
1290
|
+
visibility: Boolean(errorText),
|
|
1291
|
+
variant: "danger",
|
|
1292
|
+
className: responseClassName
|
|
1293
|
+
}
|
|
1294
|
+
)
|
|
1295
|
+
] });
|
|
1296
|
+
}
|
|
1297
|
+
function useResolvedSelectConfig({
|
|
1298
|
+
label,
|
|
1299
|
+
placeholder,
|
|
1300
|
+
shape
|
|
1301
|
+
}) {
|
|
1302
|
+
const eui = useEUIConfig();
|
|
1303
|
+
return {
|
|
1304
|
+
label: label ?? placeholder,
|
|
1305
|
+
shape: shape ?? eui?.config?.global?.shape ?? "square"
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
function useSelectFieldState(props) {
|
|
1309
|
+
const [field, meta, helpers] = formik.useField(props);
|
|
1310
|
+
return {
|
|
1311
|
+
field,
|
|
1312
|
+
helpers,
|
|
1313
|
+
meta
|
|
1314
|
+
};
|
|
1315
|
+
}
|
|
1316
|
+
function getSelectOptionLabel(options, value) {
|
|
1317
|
+
const option = options.find((item) => item.value === value);
|
|
1318
|
+
if (!option) {
|
|
1319
|
+
return "";
|
|
1320
|
+
}
|
|
1321
|
+
return String(option.label ?? "");
|
|
1322
|
+
}
|
|
1323
|
+
function Select(selectProps) {
|
|
1324
|
+
const {
|
|
1325
|
+
disabled = false,
|
|
1326
|
+
inputClassName,
|
|
1327
|
+
label,
|
|
1328
|
+
labelClassName,
|
|
1329
|
+
options,
|
|
1330
|
+
placeholder,
|
|
1331
|
+
responseClassName,
|
|
1332
|
+
shape,
|
|
1333
|
+
styles,
|
|
1334
|
+
className,
|
|
1335
|
+
onBlur,
|
|
1336
|
+
onFocus,
|
|
1337
|
+
..._props
|
|
1338
|
+
} = selectProps;
|
|
1339
|
+
const { field, helpers, meta } = useSelectFieldState(selectProps);
|
|
1340
|
+
const [focused, setFocused] = react.useState(false);
|
|
1341
|
+
const [open, setOpen] = react.useState(false);
|
|
1342
|
+
const { label: resolvedLabel, shape: resolvedShape } = useResolvedSelectConfig({
|
|
1343
|
+
label,
|
|
1344
|
+
placeholder,
|
|
1345
|
+
shape
|
|
1346
|
+
});
|
|
1347
|
+
const hasError = Boolean(meta.touched && meta.error);
|
|
1348
|
+
const errorText = hasError && typeof meta.error === "string" ? meta.error : null;
|
|
1349
|
+
const selectedLabel = getSelectOptionLabel(options, field.value ?? "");
|
|
1350
|
+
const closeOptions = () => {
|
|
1351
|
+
setOpen(false);
|
|
1352
|
+
setFocused(false);
|
|
1353
|
+
void helpers.setTouched(true);
|
|
1354
|
+
};
|
|
1355
|
+
const handleOpen = () => {
|
|
1356
|
+
if (disabled) {
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
setFocused(true);
|
|
1360
|
+
setOpen(true);
|
|
1361
|
+
};
|
|
1362
|
+
const handleSelect = (option) => {
|
|
1363
|
+
if (option.disabled) {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
void helpers.setValue(option.value);
|
|
1367
|
+
void helpers.setTouched(true);
|
|
1368
|
+
setOpen(false);
|
|
1369
|
+
setFocused(false);
|
|
1370
|
+
};
|
|
1371
|
+
const handleBlur = (event) => {
|
|
1372
|
+
setFocused(false);
|
|
1373
|
+
void helpers.setTouched(true);
|
|
1374
|
+
onBlur?.(event);
|
|
1375
|
+
};
|
|
1376
|
+
const handleFocus = (event) => {
|
|
1377
|
+
setFocused(true);
|
|
1378
|
+
onFocus?.(event);
|
|
1379
|
+
};
|
|
1380
|
+
return /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: inputRootClassName, children: [
|
|
1381
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1382
|
+
reactNative.Pressable,
|
|
1383
|
+
{
|
|
1384
|
+
accessibilityLabel: resolvedLabel,
|
|
1385
|
+
accessibilityRole: "button",
|
|
1386
|
+
accessibilityState: { disabled, expanded: open },
|
|
1387
|
+
disabled,
|
|
1388
|
+
onBlur: handleBlur,
|
|
1389
|
+
onFocus: handleFocus,
|
|
1390
|
+
onPress: handleOpen,
|
|
1391
|
+
className: cn(
|
|
1392
|
+
inputFrameClassName,
|
|
1393
|
+
"justify-center",
|
|
1394
|
+
hasError ? inputFrameErrorClassName : focused || open ? inputFrameActiveClassName : inputFrameIdleClassName,
|
|
1395
|
+
inputShapes[resolvedShape],
|
|
1396
|
+
disabled && inputFrameDisabledClassName,
|
|
1397
|
+
className,
|
|
1398
|
+
styles
|
|
1399
|
+
),
|
|
1400
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1401
|
+
reactNative.Text,
|
|
1402
|
+
{
|
|
1403
|
+
numberOfLines: 1,
|
|
1404
|
+
className: cn(
|
|
1405
|
+
inputControlClassName,
|
|
1406
|
+
"pt-5 pb-2",
|
|
1407
|
+
!selectedLabel && "text-gray-500 dark:text-gray-300",
|
|
1408
|
+
inputClassName
|
|
1409
|
+
),
|
|
1410
|
+
style: { includeFontPadding: false },
|
|
1411
|
+
children: selectedLabel
|
|
1412
|
+
}
|
|
1413
|
+
)
|
|
1414
|
+
}
|
|
1415
|
+
),
|
|
1416
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1417
|
+
InputLabel,
|
|
1418
|
+
{
|
|
1419
|
+
disabled,
|
|
1420
|
+
errored: hasError,
|
|
1421
|
+
floating: true,
|
|
1422
|
+
text: resolvedLabel,
|
|
1423
|
+
className: labelClassName
|
|
1424
|
+
}
|
|
1425
|
+
),
|
|
1426
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1427
|
+
InputResponse,
|
|
1428
|
+
{
|
|
1429
|
+
message: errorText,
|
|
1430
|
+
name: field.name,
|
|
1431
|
+
visibility: Boolean(errorText),
|
|
1432
|
+
variant: "danger",
|
|
1433
|
+
className: responseClassName
|
|
1434
|
+
}
|
|
1435
|
+
),
|
|
1436
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1437
|
+
reactNative.Modal,
|
|
1438
|
+
{
|
|
1439
|
+
animationType: "fade",
|
|
1440
|
+
onRequestClose: closeOptions,
|
|
1441
|
+
transparent: true,
|
|
1442
|
+
visible: open,
|
|
1443
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: "flex-1 justify-end bg-black/40 px-4 py-6", children: [
|
|
1444
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1445
|
+
reactNative.Pressable,
|
|
1446
|
+
{
|
|
1447
|
+
accessibilityLabel: "Close select options",
|
|
1448
|
+
accessibilityRole: "button",
|
|
1449
|
+
className: "absolute inset-0",
|
|
1450
|
+
onPress: closeOptions
|
|
1451
|
+
}
|
|
1452
|
+
),
|
|
1453
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(reactNative.View, { className: "max-h-[70%] overflow-hidden rounded-lg bg-white shadow-xl dark:bg-eui-dark-500", children: /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.ScrollView, { children: options.map((option) => {
|
|
1454
|
+
const selected = option.value === field.value;
|
|
1455
|
+
return /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1456
|
+
reactNative.Pressable,
|
|
1457
|
+
{
|
|
1458
|
+
accessibilityRole: "button",
|
|
1459
|
+
accessibilityState: {
|
|
1460
|
+
disabled: option.disabled,
|
|
1461
|
+
selected
|
|
1462
|
+
},
|
|
1463
|
+
disabled: option.disabled,
|
|
1464
|
+
onPress: () => handleSelect(option),
|
|
1465
|
+
className: cn(
|
|
1466
|
+
"min-h-12 justify-center border-b border-gray-200 px-4 py-3 dark:border-eui-dark-300",
|
|
1467
|
+
selected && "bg-eui-secondary-500/10",
|
|
1468
|
+
option.disabled && "opacity-50"
|
|
1469
|
+
),
|
|
1470
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsx(reactNative.Text, { className: "text-base font-medium text-gray-950 dark:text-gray-50", children: String(option.label) })
|
|
1471
|
+
},
|
|
1472
|
+
option.value
|
|
1473
|
+
);
|
|
1474
|
+
}) }) })
|
|
1475
|
+
] })
|
|
1476
|
+
}
|
|
1477
|
+
)
|
|
1478
|
+
] });
|
|
1479
|
+
}
|
|
1480
|
+
function useResolvedTagsConfig({
|
|
1481
|
+
label,
|
|
1482
|
+
limit = 10,
|
|
1483
|
+
placeholder,
|
|
1484
|
+
shape
|
|
1485
|
+
}) {
|
|
1486
|
+
const eui = useEUIConfig();
|
|
1487
|
+
return {
|
|
1488
|
+
label: label ?? placeholder,
|
|
1489
|
+
limit,
|
|
1490
|
+
shape: shape ?? eui?.config?.global?.shape ?? "square"
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
function useTagsFieldState(props) {
|
|
1494
|
+
const [field, meta, helpers] = formik.useField(props);
|
|
1495
|
+
return {
|
|
1496
|
+
field,
|
|
1497
|
+
helpers,
|
|
1498
|
+
meta
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
function getTagsValue(value) {
|
|
1502
|
+
if (!Array.isArray(value)) {
|
|
1503
|
+
return [];
|
|
1504
|
+
}
|
|
1505
|
+
return value.filter((tag) => typeof tag === "string");
|
|
1506
|
+
}
|
|
1507
|
+
function addTagToList(tags, value, limit) {
|
|
1508
|
+
const trimmed = value.trim();
|
|
1509
|
+
if (!trimmed || tags.includes(trimmed) || tags.length >= limit) {
|
|
1510
|
+
return tags;
|
|
1511
|
+
}
|
|
1512
|
+
return [...tags, trimmed];
|
|
1513
|
+
}
|
|
1514
|
+
function removeTagFromList(tags, index) {
|
|
1515
|
+
return tags.filter((_, tagIndex) => tagIndex !== index);
|
|
1516
|
+
}
|
|
1517
|
+
var nativeTagsInputControlStyle = {
|
|
1518
|
+
...nativeInputControlStyle,
|
|
1519
|
+
minHeight: 28,
|
|
1520
|
+
paddingBottom: 0,
|
|
1521
|
+
paddingTop: 0
|
|
1522
|
+
};
|
|
1523
|
+
function Tags(tagsProps) {
|
|
1524
|
+
const {
|
|
1525
|
+
disabled = false,
|
|
1526
|
+
inputClassName,
|
|
1527
|
+
label,
|
|
1528
|
+
labelClassName,
|
|
1529
|
+
limit,
|
|
1530
|
+
placeholder,
|
|
1531
|
+
responseClassName,
|
|
1532
|
+
shape,
|
|
1533
|
+
styles,
|
|
1534
|
+
tagClassName,
|
|
1535
|
+
removeButtonClassName,
|
|
1536
|
+
counterClassName,
|
|
1537
|
+
className,
|
|
1538
|
+
onBlur,
|
|
1539
|
+
onFocus,
|
|
1540
|
+
..._props
|
|
1541
|
+
} = tagsProps;
|
|
1542
|
+
const { field, helpers, meta } = useTagsFieldState(tagsProps);
|
|
1543
|
+
const [input, setInput] = react.useState("");
|
|
1544
|
+
const [focused, setFocused] = react.useState(false);
|
|
1545
|
+
const {
|
|
1546
|
+
label: resolvedLabel,
|
|
1547
|
+
limit: resolvedLimit,
|
|
1548
|
+
shape: resolvedShape
|
|
1549
|
+
} = useResolvedTagsConfig({
|
|
1550
|
+
label,
|
|
1551
|
+
limit,
|
|
1552
|
+
placeholder,
|
|
1553
|
+
shape
|
|
1554
|
+
});
|
|
1555
|
+
const tags = getTagsValue(field.value);
|
|
1556
|
+
const hasError = Boolean(meta.touched && meta.error);
|
|
1557
|
+
const errorText = hasError && typeof meta.error === "string" ? meta.error : null;
|
|
1558
|
+
const floating = focused || input.length > 0 || tags.length > 0;
|
|
1559
|
+
const handleAddTag = (value = input) => {
|
|
1560
|
+
if (disabled) {
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
const nextTags = addTagToList(tags, value, resolvedLimit);
|
|
1564
|
+
if (nextTags !== tags) {
|
|
1565
|
+
void helpers.setValue(nextTags);
|
|
1566
|
+
}
|
|
1567
|
+
if (value.trim()) {
|
|
1568
|
+
void helpers.setTouched(true);
|
|
1569
|
+
}
|
|
1570
|
+
setInput("");
|
|
1571
|
+
};
|
|
1572
|
+
const handleChangeText = (value) => {
|
|
1573
|
+
if (value.endsWith(",")) {
|
|
1574
|
+
handleAddTag(value.slice(0, -1));
|
|
1575
|
+
return;
|
|
1576
|
+
}
|
|
1577
|
+
setInput(value);
|
|
1578
|
+
};
|
|
1579
|
+
const handleKeyPress = (event) => {
|
|
1580
|
+
if (event.nativeEvent?.key === "Backspace" && input === "" && tags.length) {
|
|
1581
|
+
void helpers.setValue(tags.slice(0, -1));
|
|
1582
|
+
void helpers.setTouched(true);
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
const handleRemoveTag = (index) => {
|
|
1586
|
+
if (disabled) {
|
|
1587
|
+
return;
|
|
1588
|
+
}
|
|
1589
|
+
void helpers.setValue(removeTagFromList(tags, index));
|
|
1590
|
+
void helpers.setTouched(true);
|
|
1591
|
+
};
|
|
1592
|
+
const handleBlur = (event) => {
|
|
1593
|
+
setFocused(false);
|
|
1594
|
+
void helpers.setTouched(true);
|
|
1595
|
+
onBlur?.(event);
|
|
1596
|
+
};
|
|
1597
|
+
const handleFocus = (event) => {
|
|
1598
|
+
setFocused(true);
|
|
1599
|
+
onFocus?.(event);
|
|
1600
|
+
};
|
|
1601
|
+
return /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: inputRootClassName, children: [
|
|
1602
|
+
/* @__PURE__ */ jsxRuntime$1.jsxs(
|
|
1603
|
+
reactNative.View,
|
|
1604
|
+
{
|
|
1605
|
+
className: cn(
|
|
1606
|
+
inputFrameClassName,
|
|
1607
|
+
"h-auto min-h-14 flex-row flex-wrap items-center gap-2 overflow-visible px-3 pt-6 pb-7",
|
|
1608
|
+
hasError ? inputFrameErrorClassName : focused ? inputFrameActiveClassName : inputFrameIdleClassName,
|
|
1609
|
+
inputShapes[resolvedShape],
|
|
1610
|
+
disabled && inputFrameDisabledClassName,
|
|
1611
|
+
className,
|
|
1612
|
+
styles
|
|
1613
|
+
),
|
|
1614
|
+
children: [
|
|
1615
|
+
tags.map((tag, index) => /* @__PURE__ */ jsxRuntime$1.jsxs(
|
|
1616
|
+
reactNative.View,
|
|
1617
|
+
{
|
|
1618
|
+
className: cn(
|
|
1619
|
+
"max-w-full flex-row items-center gap-1 rounded bg-eui-light-300 px-2 py-1 dark:bg-eui-dark-400",
|
|
1620
|
+
tagClassName
|
|
1621
|
+
),
|
|
1622
|
+
children: [
|
|
1623
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1624
|
+
reactNative.Text,
|
|
1625
|
+
{
|
|
1626
|
+
className: "shrink text-sm font-medium text-eui-dark-700 dark:text-eui-light-300",
|
|
1627
|
+
numberOfLines: 1,
|
|
1628
|
+
style: { includeFontPadding: false },
|
|
1629
|
+
children: tag
|
|
1630
|
+
}
|
|
1631
|
+
),
|
|
1632
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1633
|
+
reactNative.Pressable,
|
|
1634
|
+
{
|
|
1635
|
+
accessibilityLabel: `Remove ${tag}`,
|
|
1636
|
+
accessibilityRole: "button",
|
|
1637
|
+
className: cn(
|
|
1638
|
+
"h-5 w-5 items-center justify-center",
|
|
1639
|
+
disabled && "opacity-50",
|
|
1640
|
+
removeButtonClassName
|
|
1641
|
+
),
|
|
1642
|
+
disabled,
|
|
1643
|
+
onPress: () => handleRemoveTag(index),
|
|
1644
|
+
children: /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1645
|
+
reactNative.Text,
|
|
1646
|
+
{
|
|
1647
|
+
className: "text-xs font-bold text-eui-danger-500",
|
|
1648
|
+
style: { includeFontPadding: false },
|
|
1649
|
+
children: "x"
|
|
1650
|
+
}
|
|
1651
|
+
)
|
|
1652
|
+
}
|
|
1653
|
+
)
|
|
1654
|
+
]
|
|
1655
|
+
},
|
|
1656
|
+
`${tag}-${index}`
|
|
1657
|
+
)),
|
|
1658
|
+
tags.length < resolvedLimit ? /* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1659
|
+
reactNative.TextInput,
|
|
1660
|
+
{
|
|
1661
|
+
accessibilityLabel: resolvedLabel,
|
|
1662
|
+
className: cn(
|
|
1663
|
+
inputControlClassName,
|
|
1664
|
+
"h-7 w-auto min-w-[120px] flex-1 p-0",
|
|
1665
|
+
inputClassName
|
|
1666
|
+
),
|
|
1667
|
+
editable: !disabled,
|
|
1668
|
+
onBlur: handleBlur,
|
|
1669
|
+
onChangeText: handleChangeText,
|
|
1670
|
+
onFocus: handleFocus,
|
|
1671
|
+
onKeyPress: handleKeyPress,
|
|
1672
|
+
onSubmitEditing: () => handleAddTag(),
|
|
1673
|
+
placeholder: "",
|
|
1674
|
+
returnKeyType: "done",
|
|
1675
|
+
style: nativeTagsInputControlStyle,
|
|
1676
|
+
underlineColorAndroid: "transparent",
|
|
1677
|
+
value: input
|
|
1678
|
+
}
|
|
1679
|
+
) : null,
|
|
1680
|
+
/* @__PURE__ */ jsxRuntime$1.jsxs(
|
|
1681
|
+
reactNative.Text,
|
|
1682
|
+
{
|
|
1683
|
+
className: cn(
|
|
1684
|
+
"absolute bottom-3 right-3 text-xs font-semibold text-eui-dark-50",
|
|
1685
|
+
counterClassName
|
|
1686
|
+
),
|
|
1687
|
+
style: { includeFontPadding: false },
|
|
1688
|
+
children: [
|
|
1689
|
+
tags.length,
|
|
1690
|
+
"/",
|
|
1691
|
+
resolvedLimit
|
|
1692
|
+
]
|
|
1693
|
+
}
|
|
1694
|
+
)
|
|
1695
|
+
]
|
|
1696
|
+
}
|
|
1697
|
+
),
|
|
1698
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1699
|
+
InputLabel,
|
|
1700
|
+
{
|
|
1701
|
+
disabled,
|
|
1702
|
+
errored: hasError,
|
|
1703
|
+
floating,
|
|
1704
|
+
text: resolvedLabel,
|
|
1705
|
+
className: labelClassName
|
|
1706
|
+
}
|
|
1707
|
+
),
|
|
1708
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1709
|
+
InputResponse,
|
|
1710
|
+
{
|
|
1711
|
+
message: errorText,
|
|
1712
|
+
name: field.name,
|
|
1713
|
+
visibility: Boolean(errorText),
|
|
1714
|
+
variant: "danger",
|
|
1715
|
+
className: responseClassName
|
|
1716
|
+
}
|
|
1717
|
+
)
|
|
1718
|
+
] });
|
|
1719
|
+
}
|
|
1720
|
+
function useResolvedTextAreaConfig({
|
|
1721
|
+
label,
|
|
1722
|
+
limit = 1e3,
|
|
1723
|
+
placeholder,
|
|
1724
|
+
shape
|
|
1725
|
+
}) {
|
|
1726
|
+
const eui = useEUIConfig();
|
|
1727
|
+
return {
|
|
1728
|
+
label: label ?? placeholder,
|
|
1729
|
+
limit,
|
|
1730
|
+
shape: shape ?? eui?.config?.global?.shape ?? "square"
|
|
1731
|
+
};
|
|
1732
|
+
}
|
|
1733
|
+
function useTextAreaFieldState(props) {
|
|
1734
|
+
const [field, meta, helpers] = formik.useField(props);
|
|
1735
|
+
return {
|
|
1736
|
+
field,
|
|
1737
|
+
helpers,
|
|
1738
|
+
meta
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
function getTextAreaCharacterCount(value) {
|
|
1742
|
+
return String(value ?? "").length;
|
|
1743
|
+
}
|
|
1744
|
+
var nativeTextAreaControlStyle = {
|
|
1745
|
+
...nativeInputControlStyle,
|
|
1746
|
+
minHeight: 128,
|
|
1747
|
+
textAlignVertical: "top"
|
|
1748
|
+
};
|
|
1749
|
+
function TextArea(textAreaProps) {
|
|
1750
|
+
const {
|
|
1751
|
+
disabled = false,
|
|
1752
|
+
inputClassName,
|
|
1753
|
+
label,
|
|
1754
|
+
labelClassName,
|
|
1755
|
+
limit,
|
|
1756
|
+
placeholder,
|
|
1757
|
+
responseClassName,
|
|
1758
|
+
shape,
|
|
1759
|
+
styles,
|
|
1760
|
+
className,
|
|
1761
|
+
onBlur,
|
|
1762
|
+
onFocus,
|
|
1763
|
+
..._props
|
|
1764
|
+
} = textAreaProps;
|
|
1765
|
+
const { field, helpers, meta } = useTextAreaFieldState(textAreaProps);
|
|
1766
|
+
const [focused, setFocused] = react.useState(false);
|
|
1767
|
+
const {
|
|
1768
|
+
label: resolvedLabel,
|
|
1769
|
+
limit: resolvedLimit,
|
|
1770
|
+
shape: resolvedShape
|
|
1771
|
+
} = useResolvedTextAreaConfig({
|
|
1772
|
+
label,
|
|
1773
|
+
limit,
|
|
1774
|
+
placeholder,
|
|
1775
|
+
shape
|
|
1776
|
+
});
|
|
1777
|
+
const hasError = Boolean(meta.touched && meta.error);
|
|
1778
|
+
const errorText = hasError && typeof meta.error === "string" ? meta.error : null;
|
|
1779
|
+
const characterCount = getTextAreaCharacterCount(field.value);
|
|
1780
|
+
const floating = focused || characterCount > 0;
|
|
1781
|
+
const handleBlur = (event) => {
|
|
1782
|
+
setFocused(false);
|
|
1783
|
+
void helpers.setTouched(true);
|
|
1784
|
+
onBlur?.(event);
|
|
1785
|
+
};
|
|
1786
|
+
const handleFocus = (event) => {
|
|
1787
|
+
setFocused(true);
|
|
1788
|
+
onFocus?.(event);
|
|
1789
|
+
};
|
|
1790
|
+
return /* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.View, { className: inputRootClassName, children: [
|
|
1791
|
+
/* @__PURE__ */ jsxRuntime$1.jsxs(
|
|
1792
|
+
reactNative.View,
|
|
1793
|
+
{
|
|
1794
|
+
className: cn(
|
|
1795
|
+
inputFrameClassName,
|
|
1796
|
+
"h-auto min-h-32 px-3",
|
|
1797
|
+
hasError ? inputFrameErrorClassName : focused ? inputFrameActiveClassName : inputFrameIdleClassName,
|
|
1798
|
+
inputShapes[resolvedShape],
|
|
1799
|
+
disabled && inputFrameDisabledClassName,
|
|
1800
|
+
className,
|
|
1801
|
+
styles
|
|
1802
|
+
),
|
|
1803
|
+
children: [
|
|
1804
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1805
|
+
reactNative.TextInput,
|
|
1806
|
+
{
|
|
1807
|
+
accessibilityLabel: resolvedLabel,
|
|
1808
|
+
className: cn(inputControlClassName, "min-h-32 pb-8", inputClassName),
|
|
1809
|
+
editable: !disabled,
|
|
1810
|
+
maxLength: resolvedLimit,
|
|
1811
|
+
multiline: true,
|
|
1812
|
+
onBlur: handleBlur,
|
|
1813
|
+
onChangeText: (value) => helpers.setValue(value),
|
|
1814
|
+
onFocus: handleFocus,
|
|
1815
|
+
placeholder: "",
|
|
1816
|
+
style: nativeTextAreaControlStyle,
|
|
1817
|
+
underlineColorAndroid: "transparent",
|
|
1818
|
+
value: field.value ?? ""
|
|
1819
|
+
}
|
|
1820
|
+
),
|
|
1821
|
+
/* @__PURE__ */ jsxRuntime$1.jsxs(reactNative.Text, { className: "absolute bottom-3 right-3 text-xs font-semibold text-eui-dark-50", children: [
|
|
1822
|
+
characterCount,
|
|
1823
|
+
"/",
|
|
1824
|
+
resolvedLimit
|
|
1825
|
+
] })
|
|
1826
|
+
]
|
|
1827
|
+
}
|
|
1828
|
+
),
|
|
1829
|
+
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1830
|
+
InputLabel,
|
|
1831
|
+
{
|
|
1832
|
+
disabled,
|
|
1833
|
+
errored: hasError,
|
|
1834
|
+
floating,
|
|
1835
|
+
text: resolvedLabel,
|
|
1836
|
+
className: labelClassName
|
|
1837
|
+
}
|
|
1838
|
+
),
|
|
1047
1839
|
/* @__PURE__ */ jsxRuntime$1.jsx(
|
|
1048
1840
|
InputResponse,
|
|
1049
1841
|
{
|
|
@@ -1059,12 +1851,17 @@ function Input(inputProps) {
|
|
|
1059
1851
|
|
|
1060
1852
|
exports.Button = Button_native_default;
|
|
1061
1853
|
exports.Checkbox = Checkbox;
|
|
1854
|
+
exports.DateSelector = DateSelector;
|
|
1062
1855
|
exports.EUIProvider = EUIProvider;
|
|
1063
1856
|
exports.Form = Form;
|
|
1064
1857
|
exports.FormResponse = FormResponse;
|
|
1065
1858
|
exports.Input = Input;
|
|
1859
|
+
exports.InputFile = InputFile;
|
|
1066
1860
|
exports.InputLabel = InputLabel;
|
|
1067
1861
|
exports.InputResponse = InputResponse;
|
|
1862
|
+
exports.Select = Select;
|
|
1863
|
+
exports.Tags = Tags;
|
|
1864
|
+
exports.TextArea = TextArea;
|
|
1068
1865
|
exports.resolveWithGlobal = resolveWithGlobal;
|
|
1069
1866
|
exports.useEUIConfig = useEUIConfig;
|
|
1070
1867
|
//# sourceMappingURL=index.native.js.map
|