@vellira-ui/react-native 2.29.0 → 2.31.0
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/README.md +2 -2
- package/dist/index.js +330 -142
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ export function Example() {
|
|
|
47
47
|
|
|
48
48
|
return (
|
|
49
49
|
<View style={{ gap: 16 }}>
|
|
50
|
-
<Input label='Email' value={email}
|
|
50
|
+
<Input label='Email' value={email} onValueChange={setEmail} />
|
|
51
51
|
<Checkbox
|
|
52
52
|
label='Accept terms'
|
|
53
53
|
description='Required to create an account.'
|
|
@@ -100,7 +100,7 @@ export function RoleSelect() {
|
|
|
100
100
|
<Select
|
|
101
101
|
label='Role'
|
|
102
102
|
value={role}
|
|
103
|
-
|
|
103
|
+
onValueChange={setRole}
|
|
104
104
|
options={[
|
|
105
105
|
{ label: 'Admin', value: 'admin' },
|
|
106
106
|
{ label: 'Editor', value: 'editor' },
|
package/dist/index.js
CHANGED
|
@@ -944,6 +944,7 @@ import { useControllableState as useControllableState2 } from "@vellira-ui/core"
|
|
|
944
944
|
import { View as View11 } from "react-native";
|
|
945
945
|
|
|
946
946
|
// src/patterns/FormField/FormField.tsx
|
|
947
|
+
import { useId } from "react";
|
|
947
948
|
import { Text as Text6, View as View10 } from "react-native";
|
|
948
949
|
|
|
949
950
|
// src/patterns/FormField/FormField.styles.ts
|
|
@@ -954,14 +955,14 @@ var createStyles12 = (theme) => StyleSheet12.create({
|
|
|
954
955
|
width: "100%",
|
|
955
956
|
minWidth: 0,
|
|
956
957
|
alignSelf: "stretch",
|
|
957
|
-
gap: theme.
|
|
958
|
+
gap: theme.components.formField.size.md.gap
|
|
958
959
|
},
|
|
959
960
|
label: {
|
|
960
961
|
color: theme.components.formField.label.fg,
|
|
961
962
|
fontFamily: theme.tokens.typography.family.medium,
|
|
962
|
-
fontSize: theme.
|
|
963
|
+
fontSize: theme.components.formField.size.md.labelFontSize,
|
|
963
964
|
fontWeight: fontWeight(theme.tokens.typography.weight.medium),
|
|
964
|
-
lineHeight: theme.
|
|
965
|
+
lineHeight: theme.components.formField.size.md.labelLineHeight
|
|
965
966
|
},
|
|
966
967
|
labelDisabled: {
|
|
967
968
|
color: theme.components.formField.disabled.labelFg
|
|
@@ -970,11 +971,25 @@ var createStyles12 = (theme) => StyleSheet12.create({
|
|
|
970
971
|
marginLeft: theme.tokens.spacing[1],
|
|
971
972
|
color: theme.components.formField.requiredMark.fg
|
|
972
973
|
},
|
|
974
|
+
optional: {
|
|
975
|
+
marginLeft: theme.components.formField.size.md.gap,
|
|
976
|
+
color: theme.components.formField.optional.fg,
|
|
977
|
+
fontFamily: theme.tokens.typography.family.regular,
|
|
978
|
+
fontSize: theme.components.formField.size.md.optionalFontSize,
|
|
979
|
+
lineHeight: theme.components.formField.size.md.optionalLineHeight
|
|
980
|
+
},
|
|
981
|
+
labelInfo: {
|
|
982
|
+
marginLeft: theme.components.formField.size.md.gap,
|
|
983
|
+
color: theme.components.formField.labelInfo.fg,
|
|
984
|
+
fontFamily: theme.tokens.typography.family.medium,
|
|
985
|
+
fontSize: theme.components.formField.size.md.labelInfoFontSize,
|
|
986
|
+
lineHeight: theme.components.formField.size.md.labelInfoSize
|
|
987
|
+
},
|
|
973
988
|
description: {
|
|
974
989
|
color: theme.components.formField.description.fg,
|
|
975
990
|
fontFamily: theme.tokens.typography.family.regular,
|
|
976
|
-
fontSize: theme.
|
|
977
|
-
lineHeight: theme.
|
|
991
|
+
fontSize: theme.components.formField.size.md.descriptionFontSize,
|
|
992
|
+
lineHeight: theme.components.formField.size.md.descriptionLineHeight
|
|
978
993
|
},
|
|
979
994
|
descriptionDisabled: {
|
|
980
995
|
color: theme.components.formField.disabled.descriptionFg
|
|
@@ -992,22 +1007,32 @@ var createStyles12 = (theme) => StyleSheet12.create({
|
|
|
992
1007
|
error: {
|
|
993
1008
|
color: theme.components.formField.helperText.error.fg,
|
|
994
1009
|
fontFamily: theme.tokens.typography.family.regular,
|
|
995
|
-
fontSize: theme.
|
|
996
|
-
lineHeight: theme.
|
|
1010
|
+
fontSize: theme.components.formField.size.md.helperTextFontSize,
|
|
1011
|
+
lineHeight: theme.components.formField.size.md.helperTextLineHeight
|
|
997
1012
|
},
|
|
998
1013
|
helperTextDisabled: {
|
|
999
1014
|
color: theme.components.formField.disabled.helperTextFg
|
|
1000
1015
|
}
|
|
1001
1016
|
});
|
|
1002
1017
|
|
|
1018
|
+
// src/patterns/FormField/FormFieldContext.ts
|
|
1019
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
1020
|
+
var FormFieldContext = createContext3(null);
|
|
1021
|
+
var useFormFieldContext = () => useContext3(FormFieldContext);
|
|
1022
|
+
|
|
1003
1023
|
// src/patterns/FormField/FormField.tsx
|
|
1004
1024
|
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1005
1025
|
function FormField({
|
|
1026
|
+
id,
|
|
1006
1027
|
label,
|
|
1007
1028
|
description,
|
|
1008
1029
|
error,
|
|
1009
1030
|
required = false,
|
|
1010
1031
|
disabled = false,
|
|
1032
|
+
invalid = false,
|
|
1033
|
+
size = "md",
|
|
1034
|
+
labelInfo,
|
|
1035
|
+
optionalText,
|
|
1011
1036
|
children,
|
|
1012
1037
|
style,
|
|
1013
1038
|
controlStyle,
|
|
@@ -1016,18 +1041,46 @@ function FormField({
|
|
|
1016
1041
|
errorStyle,
|
|
1017
1042
|
...rest
|
|
1018
1043
|
}) {
|
|
1044
|
+
const { theme } = useTheme();
|
|
1019
1045
|
const styles = useThemeStyles(createStyles12);
|
|
1046
|
+
const sizeTokens = theme.components.formField.size[size];
|
|
1047
|
+
const generatedId = useId();
|
|
1048
|
+
const controlId = id ?? generatedId;
|
|
1049
|
+
const labelId = label ? `${controlId}-label` : void 0;
|
|
1050
|
+
const descriptionId = description ? `${controlId}-description` : void 0;
|
|
1051
|
+
const errorId = error ? `${controlId}-error` : void 0;
|
|
1052
|
+
const isInvalid = invalid || Boolean(error);
|
|
1053
|
+
const contextValue = {
|
|
1054
|
+
controlId,
|
|
1055
|
+
labelId,
|
|
1056
|
+
descriptionId,
|
|
1057
|
+
errorId,
|
|
1058
|
+
required,
|
|
1059
|
+
disabled,
|
|
1060
|
+
invalid: isInvalid,
|
|
1061
|
+
size,
|
|
1062
|
+
ariaLabelledBy: labelId,
|
|
1063
|
+
ariaDescribedBy: [descriptionId, errorId].filter(Boolean).join(" ") || void 0
|
|
1064
|
+
};
|
|
1020
1065
|
return /* @__PURE__ */ jsxs7(
|
|
1021
1066
|
View10,
|
|
1022
1067
|
{
|
|
1023
1068
|
...rest,
|
|
1024
1069
|
accessibilityState: disabled ? { disabled: true } : void 0,
|
|
1025
|
-
style: [styles.root, style],
|
|
1070
|
+
style: [styles.root, { gap: sizeTokens.gap }, style],
|
|
1026
1071
|
children: [
|
|
1027
1072
|
label && (typeof label === "string" || typeof label === "number" ? /* @__PURE__ */ jsxs7(
|
|
1028
1073
|
Text6,
|
|
1029
1074
|
{
|
|
1030
|
-
style: [
|
|
1075
|
+
style: [
|
|
1076
|
+
styles.label,
|
|
1077
|
+
{
|
|
1078
|
+
fontSize: sizeTokens.labelFontSize,
|
|
1079
|
+
lineHeight: sizeTokens.labelLineHeight
|
|
1080
|
+
},
|
|
1081
|
+
disabled && styles.labelDisabled,
|
|
1082
|
+
labelStyle
|
|
1083
|
+
],
|
|
1031
1084
|
children: [
|
|
1032
1085
|
label,
|
|
1033
1086
|
required && /* @__PURE__ */ jsx14(
|
|
@@ -1038,6 +1091,32 @@ function FormField({
|
|
|
1038
1091
|
importantForAccessibility: "no",
|
|
1039
1092
|
children: " *"
|
|
1040
1093
|
}
|
|
1094
|
+
),
|
|
1095
|
+
!required && optionalText && /* @__PURE__ */ jsx14(
|
|
1096
|
+
Text6,
|
|
1097
|
+
{
|
|
1098
|
+
style: [
|
|
1099
|
+
styles.optional,
|
|
1100
|
+
{
|
|
1101
|
+
fontSize: sizeTokens.optionalFontSize,
|
|
1102
|
+
lineHeight: sizeTokens.optionalLineHeight
|
|
1103
|
+
}
|
|
1104
|
+
],
|
|
1105
|
+
children: optionalText
|
|
1106
|
+
}
|
|
1107
|
+
),
|
|
1108
|
+
labelInfo && /* @__PURE__ */ jsx14(
|
|
1109
|
+
Text6,
|
|
1110
|
+
{
|
|
1111
|
+
style: [
|
|
1112
|
+
styles.labelInfo,
|
|
1113
|
+
{
|
|
1114
|
+
fontSize: sizeTokens.labelInfoFontSize,
|
|
1115
|
+
lineHeight: sizeTokens.labelInfoSize
|
|
1116
|
+
}
|
|
1117
|
+
],
|
|
1118
|
+
children: labelInfo
|
|
1119
|
+
}
|
|
1041
1120
|
)
|
|
1042
1121
|
]
|
|
1043
1122
|
}
|
|
@@ -1051,26 +1130,36 @@ function FormField({
|
|
|
1051
1130
|
importantForAccessibility: "no",
|
|
1052
1131
|
children: "*"
|
|
1053
1132
|
}
|
|
1054
|
-
)
|
|
1133
|
+
),
|
|
1134
|
+
!required && optionalText,
|
|
1135
|
+
labelInfo
|
|
1055
1136
|
] })),
|
|
1056
1137
|
description && (typeof description === "string" || typeof description === "number" ? /* @__PURE__ */ jsx14(
|
|
1057
1138
|
Text6,
|
|
1058
1139
|
{
|
|
1059
1140
|
style: [
|
|
1060
1141
|
styles.description,
|
|
1142
|
+
{
|
|
1143
|
+
fontSize: sizeTokens.descriptionFontSize,
|
|
1144
|
+
lineHeight: sizeTokens.descriptionLineHeight
|
|
1145
|
+
},
|
|
1061
1146
|
disabled && styles.descriptionDisabled,
|
|
1062
1147
|
descriptionStyle
|
|
1063
1148
|
],
|
|
1064
1149
|
children: description
|
|
1065
1150
|
}
|
|
1066
1151
|
) : description),
|
|
1067
|
-
/* @__PURE__ */ jsx14(View10, { style: [styles.control, controlStyle], children }),
|
|
1152
|
+
/* @__PURE__ */ jsx14(FormFieldContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx14(View10, { style: [styles.control, { gap: sizeTokens.gap }, controlStyle], children }) }),
|
|
1068
1153
|
error && (typeof error === "string" || typeof error === "number" ? /* @__PURE__ */ jsx14(
|
|
1069
1154
|
Text6,
|
|
1070
1155
|
{
|
|
1071
1156
|
accessibilityLiveRegion: "polite",
|
|
1072
1157
|
style: [
|
|
1073
1158
|
styles.error,
|
|
1159
|
+
{
|
|
1160
|
+
fontSize: sizeTokens.helperTextFontSize,
|
|
1161
|
+
lineHeight: sizeTokens.helperTextLineHeight
|
|
1162
|
+
},
|
|
1074
1163
|
disabled && styles.helperTextDisabled,
|
|
1075
1164
|
errorStyle
|
|
1076
1165
|
],
|
|
@@ -1101,11 +1190,11 @@ var createStyles13 = (theme) => StyleSheet13.create({
|
|
|
1101
1190
|
});
|
|
1102
1191
|
|
|
1103
1192
|
// src/components/RadioGroup/RadioGroupContext.tsx
|
|
1104
|
-
import { createContext as
|
|
1105
|
-
var RadioGroupContext =
|
|
1193
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1194
|
+
var RadioGroupContext = createContext4(null);
|
|
1106
1195
|
var RadioGroupProvider = RadioGroupContext.Provider;
|
|
1107
1196
|
function useRadioGroupContext() {
|
|
1108
|
-
return
|
|
1197
|
+
return useContext4(RadioGroupContext);
|
|
1109
1198
|
}
|
|
1110
1199
|
|
|
1111
1200
|
// src/components/RadioGroup/RadioGroup.tsx
|
|
@@ -1459,8 +1548,11 @@ function Select({
|
|
|
1459
1548
|
description,
|
|
1460
1549
|
value,
|
|
1461
1550
|
defaultValue,
|
|
1462
|
-
|
|
1463
|
-
options,
|
|
1551
|
+
onValueChange,
|
|
1552
|
+
options: optionsProp,
|
|
1553
|
+
multiple = false,
|
|
1554
|
+
maxSelected,
|
|
1555
|
+
closeOnSelect,
|
|
1464
1556
|
placeholder = "Select...",
|
|
1465
1557
|
size = "md",
|
|
1466
1558
|
required = false,
|
|
@@ -1475,24 +1567,39 @@ function Select({
|
|
|
1475
1567
|
}) {
|
|
1476
1568
|
const { theme } = useTheme();
|
|
1477
1569
|
const styles = useThemeStyles(createStyles15);
|
|
1478
|
-
const
|
|
1570
|
+
const options = optionsProp ?? [];
|
|
1571
|
+
const {
|
|
1572
|
+
selectedValue,
|
|
1573
|
+
selectedValues,
|
|
1574
|
+
selectedOption,
|
|
1575
|
+
selectedOptions,
|
|
1576
|
+
isOpen,
|
|
1577
|
+
setIsOpen,
|
|
1578
|
+
selectValue
|
|
1579
|
+
} = useSelect({
|
|
1479
1580
|
value,
|
|
1480
1581
|
defaultValue,
|
|
1481
|
-
|
|
1582
|
+
onValueChange,
|
|
1482
1583
|
options,
|
|
1584
|
+
multiple,
|
|
1585
|
+
maxSelected,
|
|
1586
|
+
closeOnSelect,
|
|
1483
1587
|
disabled
|
|
1484
1588
|
});
|
|
1485
|
-
const
|
|
1589
|
+
const resolvedSelectedValues = selectedValues ?? [];
|
|
1590
|
+
const resolvedSelectedOptions = selectedOptions ?? [];
|
|
1591
|
+
const selectedValueText = Array.isArray(selectedValue) ? selectedValue[0] ?? "" : selectedValue ?? "";
|
|
1592
|
+
const [draftValue, setDraftValue] = useState2(selectedValueText);
|
|
1486
1593
|
const hasError = !!error;
|
|
1487
1594
|
useEffect2(() => {
|
|
1488
1595
|
if (isOpen) {
|
|
1489
|
-
setDraftValue(
|
|
1596
|
+
setDraftValue(selectedValueText);
|
|
1490
1597
|
}
|
|
1491
|
-
}, [isOpen,
|
|
1598
|
+
}, [isOpen, selectedValueText]);
|
|
1492
1599
|
const resolvedLabel = accessibilityLabel ?? label ?? selectedOption?.label ?? placeholder ?? "Select";
|
|
1493
1600
|
const openPicker = () => {
|
|
1494
1601
|
if (disabled) return;
|
|
1495
|
-
setDraftValue(
|
|
1602
|
+
setDraftValue(selectedValueText);
|
|
1496
1603
|
setIsOpen(true);
|
|
1497
1604
|
};
|
|
1498
1605
|
const closePicker = () => {
|
|
@@ -1511,9 +1618,10 @@ function Select({
|
|
|
1511
1618
|
setIsOpen(false);
|
|
1512
1619
|
return;
|
|
1513
1620
|
}
|
|
1514
|
-
|
|
1621
|
+
selectValue(draftValue);
|
|
1515
1622
|
setIsOpen(false);
|
|
1516
1623
|
};
|
|
1624
|
+
const displayText = multiple && resolvedSelectedOptions.length ? resolvedSelectedOptions.map((option) => option.label).join(", ") : selectedOption?.label ?? placeholder;
|
|
1517
1625
|
return /* @__PURE__ */ jsxs9(
|
|
1518
1626
|
FormField,
|
|
1519
1627
|
{
|
|
@@ -1527,8 +1635,8 @@ function Select({
|
|
|
1527
1635
|
/* @__PURE__ */ jsx17(
|
|
1528
1636
|
SelectTrigger,
|
|
1529
1637
|
{
|
|
1530
|
-
displayText
|
|
1531
|
-
isPlaceholder:
|
|
1638
|
+
displayText,
|
|
1639
|
+
isPlaceholder: resolvedSelectedValues.length === 0,
|
|
1532
1640
|
isOpen,
|
|
1533
1641
|
size,
|
|
1534
1642
|
disabled,
|
|
@@ -1642,11 +1750,11 @@ Select.displayName = "Select";
|
|
|
1642
1750
|
import { View as View14 } from "react-native";
|
|
1643
1751
|
|
|
1644
1752
|
// src/components/Tabs/TabsContext.tsx
|
|
1645
|
-
import { createContext as
|
|
1646
|
-
var TabsContext =
|
|
1753
|
+
import { createContext as createContext5, useContext as useContext5 } from "react";
|
|
1754
|
+
var TabsContext = createContext5(null);
|
|
1647
1755
|
var TabsProvider = TabsContext.Provider;
|
|
1648
1756
|
var useTabs = () => {
|
|
1649
|
-
const context =
|
|
1757
|
+
const context = useContext5(TabsContext);
|
|
1650
1758
|
if (!context) {
|
|
1651
1759
|
throw new Error("Tabs components must be used inside <Tabs>.");
|
|
1652
1760
|
}
|
|
@@ -2805,7 +2913,6 @@ import { Pressable as Pressable12, Text as Text13, TextInput, View as View21 } f
|
|
|
2805
2913
|
|
|
2806
2914
|
// src/primitives/Input/Input.styles.ts
|
|
2807
2915
|
import { StyleSheet as StyleSheet23 } from "react-native";
|
|
2808
|
-
var getPlaceholderTextColor = (theme) => theme.components.input.default.placeholder;
|
|
2809
2916
|
var getDisabledPlaceholderTextColor = (theme) => theme.components.input.disabled.placeholder;
|
|
2810
2917
|
var resolveRingColor = (ring) => typeof ring === "string" ? ring : ring.color;
|
|
2811
2918
|
var createStyles23 = (theme) => StyleSheet23.create({
|
|
@@ -2867,6 +2974,24 @@ var createStyles23 = (theme) => StyleSheet23.create({
|
|
|
2867
2974
|
alignItems: "center",
|
|
2868
2975
|
justifyContent: "center"
|
|
2869
2976
|
},
|
|
2977
|
+
revealButton: {
|
|
2978
|
+
position: "absolute",
|
|
2979
|
+
right: theme.tokens.spacing[3],
|
|
2980
|
+
top: "50%",
|
|
2981
|
+
zIndex: 1,
|
|
2982
|
+
minWidth: 40,
|
|
2983
|
+
height: 28,
|
|
2984
|
+
marginTop: -14,
|
|
2985
|
+
borderRadius: theme.tokens.radius.sm,
|
|
2986
|
+
alignItems: "center",
|
|
2987
|
+
justifyContent: "center"
|
|
2988
|
+
},
|
|
2989
|
+
revealButtonText: {
|
|
2990
|
+
color: theme.components.input.icon.muted,
|
|
2991
|
+
fontFamily: theme.tokens.typography.family.medium,
|
|
2992
|
+
fontSize: theme.tokens.typography.size.xs,
|
|
2993
|
+
lineHeight: theme.tokens.typography.lineHeight.xs
|
|
2994
|
+
},
|
|
2870
2995
|
clearButtonText: {
|
|
2871
2996
|
color: theme.components.input.clearButton.fg,
|
|
2872
2997
|
fontSize: 16,
|
|
@@ -2920,20 +3045,6 @@ var createStyles23 = (theme) => StyleSheet23.create({
|
|
|
2920
3045
|
shadowRadius: 6,
|
|
2921
3046
|
elevation: 1
|
|
2922
3047
|
},
|
|
2923
|
-
success: {
|
|
2924
|
-
borderColor: theme.components.input.success.border
|
|
2925
|
-
},
|
|
2926
|
-
successFocused: {
|
|
2927
|
-
borderColor: theme.components.input.success.border,
|
|
2928
|
-
shadowColor: resolveRingColor(theme.components.input.success.ring),
|
|
2929
|
-
shadowOffset: {
|
|
2930
|
-
width: 0,
|
|
2931
|
-
height: 0
|
|
2932
|
-
},
|
|
2933
|
-
shadowOpacity: 0.18,
|
|
2934
|
-
shadowRadius: 6,
|
|
2935
|
-
elevation: 1
|
|
2936
|
-
},
|
|
2937
3048
|
readOnly: {
|
|
2938
3049
|
color: theme.components.input.readOnly.fg,
|
|
2939
3050
|
borderColor: theme.components.input.readOnly.border,
|
|
@@ -2976,24 +3087,48 @@ var autoCorrectByInputType = {
|
|
|
2976
3087
|
url: false,
|
|
2977
3088
|
search: false
|
|
2978
3089
|
};
|
|
3090
|
+
var applyPatternMask = (value, pattern) => {
|
|
3091
|
+
const digits = value.replace(/\D/g, "");
|
|
3092
|
+
let digitIndex = 0;
|
|
3093
|
+
let maskedValue = "";
|
|
3094
|
+
for (const character of pattern) {
|
|
3095
|
+
if (character === "#") {
|
|
3096
|
+
const nextDigit = digits[digitIndex];
|
|
3097
|
+
if (!nextDigit) break;
|
|
3098
|
+
maskedValue += nextDigit;
|
|
3099
|
+
digitIndex += 1;
|
|
3100
|
+
continue;
|
|
3101
|
+
}
|
|
3102
|
+
if (digitIndex < digits.length) {
|
|
3103
|
+
maskedValue += character;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
return maskedValue;
|
|
3107
|
+
};
|
|
3108
|
+
var applyMask = (value, mask) => {
|
|
3109
|
+
if (!mask) return value;
|
|
3110
|
+
return typeof mask === "function" ? mask(value) : applyPatternMask(value, mask);
|
|
3111
|
+
};
|
|
2979
3112
|
var Input = forwardRef3(
|
|
2980
3113
|
({
|
|
2981
3114
|
label,
|
|
2982
3115
|
description,
|
|
2983
3116
|
value,
|
|
2984
3117
|
defaultValue,
|
|
2985
|
-
|
|
3118
|
+
onValueChange,
|
|
2986
3119
|
placeholder,
|
|
2987
|
-
size
|
|
3120
|
+
size,
|
|
2988
3121
|
error,
|
|
3122
|
+
invalid = false,
|
|
2989
3123
|
disabled = false,
|
|
2990
3124
|
required = false,
|
|
3125
|
+
loading = false,
|
|
2991
3126
|
readOnly = false,
|
|
2992
3127
|
type = "text",
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3128
|
+
startIcon,
|
|
3129
|
+
endIcon,
|
|
3130
|
+
startIconTone = "default",
|
|
3131
|
+
endIconTone = "default",
|
|
2997
3132
|
clearIcon,
|
|
2998
3133
|
clearIconTone = "danger",
|
|
2999
3134
|
iconSize,
|
|
@@ -3012,19 +3147,38 @@ var Input = forwardRef3(
|
|
|
3012
3147
|
maxLength,
|
|
3013
3148
|
clearable,
|
|
3014
3149
|
onClear,
|
|
3150
|
+
color = "primary",
|
|
3151
|
+
variant = "outline",
|
|
3152
|
+
revealPassword = false,
|
|
3153
|
+
showCounter: _showCounter,
|
|
3154
|
+
mask,
|
|
3155
|
+
format,
|
|
3156
|
+
parse,
|
|
3015
3157
|
...props
|
|
3016
3158
|
}, ref) => {
|
|
3017
3159
|
const { theme } = useTheme();
|
|
3018
3160
|
const styles = useThemeStyles(createStyles23);
|
|
3161
|
+
const field = useFormFieldContext();
|
|
3162
|
+
const hasOwnField = Boolean(label || description || error);
|
|
3019
3163
|
const [isFocused, setIsFocused] = useState6(false);
|
|
3020
3164
|
const [uncontrolledValue, setUncontrolledValue] = useState6(
|
|
3021
3165
|
defaultValue ?? ""
|
|
3022
3166
|
);
|
|
3023
3167
|
const isControlled = value !== void 0;
|
|
3024
3168
|
const currentValue = isControlled ? value : uncontrolledValue;
|
|
3169
|
+
const displayValue = format ? format(currentValue) : currentValue;
|
|
3025
3170
|
const hasValue = currentValue !== "";
|
|
3026
|
-
const
|
|
3171
|
+
const resolvedSize = size ?? field?.size ?? "md";
|
|
3172
|
+
const inputColorPalette = theme.components.input[color];
|
|
3173
|
+
const inputPalette = inputColorPalette[variant];
|
|
3174
|
+
const inputState = isFocused ? inputPalette.focus : inputPalette.default;
|
|
3175
|
+
const isInvalid = invalid || Boolean(error) || !hasOwnField && Boolean(field?.invalid);
|
|
3176
|
+
const isDisabled = disabled || !hasOwnField && Boolean(field?.disabled);
|
|
3177
|
+
const isRequired = required || !hasOwnField && Boolean(field?.required);
|
|
3178
|
+
const isReadOnly = readOnly || loading;
|
|
3179
|
+
const placeholderTextColor = isDisabled ? getDisabledPlaceholderTextColor(theme) : readOnly ? theme.components.input.readOnly.placeholder : inputState.placeholder;
|
|
3027
3180
|
const isPassword = type === "password";
|
|
3181
|
+
const [isPasswordRevealed, setIsPasswordRevealed] = useState6(false);
|
|
3028
3182
|
const resolvedIconSize = iconSize ?? 16;
|
|
3029
3183
|
const handleFocus = (event) => {
|
|
3030
3184
|
setIsFocused(true);
|
|
@@ -3035,114 +3189,148 @@ var Input = forwardRef3(
|
|
|
3035
3189
|
onBlur?.(event);
|
|
3036
3190
|
};
|
|
3037
3191
|
const handleChangeText = (nextValue) => {
|
|
3192
|
+
const parsedValue = parse ? parse(nextValue) : nextValue;
|
|
3193
|
+
const maskedValue = applyMask(parsedValue, mask);
|
|
3038
3194
|
if (!isControlled) {
|
|
3039
|
-
setUncontrolledValue(
|
|
3195
|
+
setUncontrolledValue(maskedValue);
|
|
3040
3196
|
}
|
|
3041
|
-
|
|
3197
|
+
onValueChange?.(maskedValue);
|
|
3042
3198
|
};
|
|
3043
3199
|
const handleClear = () => {
|
|
3044
3200
|
if (!isControlled) {
|
|
3045
3201
|
setUncontrolledValue("");
|
|
3046
3202
|
}
|
|
3203
|
+
onValueChange?.("");
|
|
3047
3204
|
onClear?.();
|
|
3048
3205
|
};
|
|
3049
|
-
const showClearButton = clearable && hasValue && !
|
|
3050
|
-
const
|
|
3051
|
-
const
|
|
3052
|
-
const
|
|
3053
|
-
const
|
|
3206
|
+
const showClearButton = clearable && hasValue && !isDisabled && !isReadOnly;
|
|
3207
|
+
const showRevealButton = revealPassword && isPassword && !isDisabled;
|
|
3208
|
+
const showRightIcon = !showClearButton && !showRevealButton && Boolean(endIcon);
|
|
3209
|
+
const startIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[startIconTone];
|
|
3210
|
+
const endIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[endIconTone];
|
|
3211
|
+
const clearIconColor = isDisabled ? theme.components.input.disabled.icon : theme.components.input.icon[clearIconTone];
|
|
3212
|
+
const control = /* @__PURE__ */ jsxs14(View21, { style: styles.inputWrapper, children: [
|
|
3213
|
+
startIcon && /* @__PURE__ */ jsx25(
|
|
3214
|
+
View21,
|
|
3215
|
+
{
|
|
3216
|
+
pointerEvents: "none",
|
|
3217
|
+
style: styles.leftIcon,
|
|
3218
|
+
accessibilityElementsHidden: true,
|
|
3219
|
+
importantForAccessibility: "no",
|
|
3220
|
+
children: cloneElement6(startIcon, {
|
|
3221
|
+
color: startIconColor,
|
|
3222
|
+
size: resolvedIconSize
|
|
3223
|
+
})
|
|
3224
|
+
}
|
|
3225
|
+
),
|
|
3226
|
+
/* @__PURE__ */ jsx25(
|
|
3227
|
+
TextInput,
|
|
3228
|
+
{
|
|
3229
|
+
...props,
|
|
3230
|
+
ref,
|
|
3231
|
+
nativeID: props.nativeID ?? (!hasOwnField ? field?.controlId : void 0),
|
|
3232
|
+
value: displayValue,
|
|
3233
|
+
onChangeText: handleChangeText,
|
|
3234
|
+
editable: !isDisabled && !isReadOnly,
|
|
3235
|
+
placeholder,
|
|
3236
|
+
keyboardType: keyboardType ?? keyboardTypeByInputType[type],
|
|
3237
|
+
secureTextEntry: secureTextEntry ?? (isPassword && !isPasswordRevealed),
|
|
3238
|
+
autoCapitalize: autoCapitalize ?? autoCapitalizeByInputType[type],
|
|
3239
|
+
autoCorrect: autoCorrect ?? autoCorrectByInputType[type],
|
|
3240
|
+
onBlur: handleBlur,
|
|
3241
|
+
onFocus: handleFocus,
|
|
3242
|
+
autoFocus,
|
|
3243
|
+
maxLength,
|
|
3244
|
+
testID,
|
|
3245
|
+
placeholderTextColor,
|
|
3246
|
+
accessibilityLabel: accessibilityLabel ?? label,
|
|
3247
|
+
accessibilityHint,
|
|
3248
|
+
accessibilityState: { disabled: isDisabled },
|
|
3249
|
+
accessibilityLabelledBy: !hasOwnField ? field?.labelId : void 0,
|
|
3250
|
+
"aria-describedby": !hasOwnField ? field?.ariaDescribedBy : void 0,
|
|
3251
|
+
style: [
|
|
3252
|
+
styles.input,
|
|
3253
|
+
{
|
|
3254
|
+
color: inputState.fg,
|
|
3255
|
+
backgroundColor: inputState.bg,
|
|
3256
|
+
borderColor: inputState.border
|
|
3257
|
+
},
|
|
3258
|
+
styles[resolvedSize],
|
|
3259
|
+
inputStyle,
|
|
3260
|
+
startIcon && styles.inputWithLeftAdornment,
|
|
3261
|
+
(showRightIcon || showClearButton || showRevealButton) && styles.inputWithRightAdornment,
|
|
3262
|
+
isFocused && !isDisabled && !isReadOnly && {
|
|
3263
|
+
color: inputPalette.focus.fg,
|
|
3264
|
+
backgroundColor: inputPalette.focus.bg,
|
|
3265
|
+
borderColor: inputPalette.focus.border,
|
|
3266
|
+
shadowColor: inputColorPalette.ring,
|
|
3267
|
+
shadowOffset: {
|
|
3268
|
+
width: 0,
|
|
3269
|
+
height: 0
|
|
3270
|
+
},
|
|
3271
|
+
shadowOpacity: 0.18,
|
|
3272
|
+
shadowRadius: 6,
|
|
3273
|
+
elevation: 1
|
|
3274
|
+
},
|
|
3275
|
+
isInvalid && styles.error,
|
|
3276
|
+
isFocused && isInvalid && !isDisabled && !isReadOnly && styles.errorFocused,
|
|
3277
|
+
isReadOnly && !isDisabled && styles.readOnly,
|
|
3278
|
+
isDisabled && styles.disabled
|
|
3279
|
+
]
|
|
3280
|
+
}
|
|
3281
|
+
),
|
|
3282
|
+
showClearButton ? /* @__PURE__ */ jsx25(
|
|
3283
|
+
Pressable12,
|
|
3284
|
+
{
|
|
3285
|
+
accessibilityRole: "button",
|
|
3286
|
+
accessibilityLabel: "Clear input",
|
|
3287
|
+
hitSlop: 8,
|
|
3288
|
+
onPress: handleClear,
|
|
3289
|
+
style: styles.clearButton,
|
|
3290
|
+
children: clearIcon ? cloneElement6(clearIcon, {
|
|
3291
|
+
color: clearIconColor,
|
|
3292
|
+
size: resolvedIconSize
|
|
3293
|
+
}) : /* @__PURE__ */ jsx25(Text13, { style: [styles.clearButtonText, { color: clearIconColor }], children: "\xD7" })
|
|
3294
|
+
}
|
|
3295
|
+
) : showRevealButton ? /* @__PURE__ */ jsx25(
|
|
3296
|
+
Pressable12,
|
|
3297
|
+
{
|
|
3298
|
+
accessibilityRole: "button",
|
|
3299
|
+
accessibilityLabel: isPasswordRevealed ? "Hide password" : "Show password",
|
|
3300
|
+
hitSlop: 8,
|
|
3301
|
+
onPress: () => setIsPasswordRevealed((revealed) => !revealed),
|
|
3302
|
+
style: styles.revealButton,
|
|
3303
|
+
children: /* @__PURE__ */ jsx25(Text13, { style: styles.revealButtonText, children: isPasswordRevealed ? "Hide" : "Show" })
|
|
3304
|
+
}
|
|
3305
|
+
) : showRightIcon && endIcon && /* @__PURE__ */ jsx25(
|
|
3306
|
+
View21,
|
|
3307
|
+
{
|
|
3308
|
+
pointerEvents: "none",
|
|
3309
|
+
style: styles.rightIcon,
|
|
3310
|
+
accessibilityElementsHidden: true,
|
|
3311
|
+
importantForAccessibility: "no",
|
|
3312
|
+
children: cloneElement6(endIcon, {
|
|
3313
|
+
color: endIconColor,
|
|
3314
|
+
size: resolvedIconSize
|
|
3315
|
+
})
|
|
3316
|
+
}
|
|
3317
|
+
)
|
|
3318
|
+
] });
|
|
3319
|
+
if (!hasOwnField && field) {
|
|
3320
|
+
return control;
|
|
3321
|
+
}
|
|
3054
3322
|
return /* @__PURE__ */ jsx25(
|
|
3055
3323
|
FormField,
|
|
3056
3324
|
{
|
|
3057
3325
|
label,
|
|
3058
3326
|
description,
|
|
3059
3327
|
error,
|
|
3060
|
-
required,
|
|
3061
|
-
disabled,
|
|
3328
|
+
required: isRequired,
|
|
3329
|
+
disabled: isDisabled,
|
|
3330
|
+
invalid: isInvalid,
|
|
3331
|
+
size: resolvedSize,
|
|
3062
3332
|
style: containerStyle,
|
|
3063
|
-
children:
|
|
3064
|
-
leftIcon && /* @__PURE__ */ jsx25(
|
|
3065
|
-
View21,
|
|
3066
|
-
{
|
|
3067
|
-
pointerEvents: "none",
|
|
3068
|
-
style: styles.leftIcon,
|
|
3069
|
-
accessibilityElementsHidden: true,
|
|
3070
|
-
importantForAccessibility: "no",
|
|
3071
|
-
children: cloneElement6(leftIcon, {
|
|
3072
|
-
color: leftIconColor,
|
|
3073
|
-
size: resolvedIconSize
|
|
3074
|
-
})
|
|
3075
|
-
}
|
|
3076
|
-
),
|
|
3077
|
-
/* @__PURE__ */ jsx25(
|
|
3078
|
-
TextInput,
|
|
3079
|
-
{
|
|
3080
|
-
...props,
|
|
3081
|
-
ref,
|
|
3082
|
-
value: currentValue,
|
|
3083
|
-
onChangeText: handleChangeText,
|
|
3084
|
-
editable: !disabled && !readOnly,
|
|
3085
|
-
placeholder,
|
|
3086
|
-
keyboardType: keyboardType ?? keyboardTypeByInputType[type],
|
|
3087
|
-
secureTextEntry: secureTextEntry ?? isPassword,
|
|
3088
|
-
autoCapitalize: autoCapitalize ?? autoCapitalizeByInputType[type],
|
|
3089
|
-
autoCorrect: autoCorrect ?? autoCorrectByInputType[type],
|
|
3090
|
-
onBlur: handleBlur,
|
|
3091
|
-
onFocus: handleFocus,
|
|
3092
|
-
autoFocus,
|
|
3093
|
-
maxLength,
|
|
3094
|
-
testID,
|
|
3095
|
-
placeholderTextColor,
|
|
3096
|
-
accessibilityLabel: accessibilityLabel ?? label,
|
|
3097
|
-
accessibilityHint,
|
|
3098
|
-
accessibilityState: { disabled },
|
|
3099
|
-
style: [
|
|
3100
|
-
styles.input,
|
|
3101
|
-
styles[size],
|
|
3102
|
-
inputStyle,
|
|
3103
|
-
leftIcon && styles.inputWithLeftAdornment,
|
|
3104
|
-
(showRightIcon || showClearButton) && styles.inputWithRightAdornment,
|
|
3105
|
-
isFocused && !disabled && !readOnly && styles.focused,
|
|
3106
|
-
error && styles.error,
|
|
3107
|
-
isFocused && error && !disabled && !readOnly && styles.errorFocused,
|
|
3108
|
-
readOnly && !disabled && styles.readOnly,
|
|
3109
|
-
disabled && styles.disabled
|
|
3110
|
-
]
|
|
3111
|
-
}
|
|
3112
|
-
),
|
|
3113
|
-
showClearButton ? /* @__PURE__ */ jsx25(
|
|
3114
|
-
Pressable12,
|
|
3115
|
-
{
|
|
3116
|
-
accessibilityRole: "button",
|
|
3117
|
-
accessibilityLabel: "Clear input",
|
|
3118
|
-
hitSlop: 8,
|
|
3119
|
-
onPress: handleClear,
|
|
3120
|
-
style: styles.clearButton,
|
|
3121
|
-
children: clearIcon ? cloneElement6(clearIcon, {
|
|
3122
|
-
color: clearIconColor,
|
|
3123
|
-
size: resolvedIconSize
|
|
3124
|
-
}) : /* @__PURE__ */ jsx25(
|
|
3125
|
-
Text13,
|
|
3126
|
-
{
|
|
3127
|
-
style: [styles.clearButtonText, { color: clearIconColor }],
|
|
3128
|
-
children: "\xD7"
|
|
3129
|
-
}
|
|
3130
|
-
)
|
|
3131
|
-
}
|
|
3132
|
-
) : showRightIcon && rightIcon && /* @__PURE__ */ jsx25(
|
|
3133
|
-
View21,
|
|
3134
|
-
{
|
|
3135
|
-
pointerEvents: "none",
|
|
3136
|
-
style: styles.rightIcon,
|
|
3137
|
-
accessibilityElementsHidden: true,
|
|
3138
|
-
importantForAccessibility: "no",
|
|
3139
|
-
children: cloneElement6(rightIcon, {
|
|
3140
|
-
color: rightIconColor,
|
|
3141
|
-
size: resolvedIconSize
|
|
3142
|
-
})
|
|
3143
|
-
}
|
|
3144
|
-
)
|
|
3145
|
-
] })
|
|
3333
|
+
children: control
|
|
3146
3334
|
}
|
|
3147
3335
|
);
|
|
3148
3336
|
}
|