jfs-components 0.0.73 → 0.0.74
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/CHANGELOG.md +23 -6
- package/lib/commonjs/components/AccountCard/AccountCard.js +247 -0
- package/lib/commonjs/components/AppBar/AppBar.js +17 -11
- package/lib/commonjs/components/CardBankAccount/CardBankAccount.js +18 -2
- package/lib/commonjs/components/CheckboxItem/CheckboxItem.js +40 -25
- package/lib/commonjs/components/Dropdown/Dropdown.js +214 -0
- package/lib/commonjs/components/DropdownInput/DropdownInput.js +542 -0
- package/lib/commonjs/components/FormField/FormField.js +328 -178
- package/lib/commonjs/components/LottieIntroBlock/LottieIntroBlock.js +150 -0
- package/lib/commonjs/components/PageHero/PageHero.js +153 -0
- package/lib/commonjs/components/PoweredByLabel/PoweredByLabel.js +135 -0
- package/lib/commonjs/components/PoweredByLabel/finvu.png +0 -0
- package/lib/commonjs/components/Text/Text.js +9 -2
- package/lib/commonjs/components/Tooltip/Tooltip.js +34 -27
- package/lib/commonjs/components/index.js +60 -0
- package/lib/commonjs/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/commonjs/icons/registry.js +1 -1
- package/lib/module/components/AccountCard/AccountCard.js +241 -0
- package/lib/module/components/AppBar/AppBar.js +17 -11
- package/lib/module/components/CardBankAccount/CardBankAccount.js +17 -2
- package/lib/module/components/CheckboxItem/CheckboxItem.js +41 -26
- package/lib/module/components/Dropdown/Dropdown.js +206 -0
- package/lib/module/components/DropdownInput/DropdownInput.js +536 -0
- package/lib/module/components/FormField/FormField.js +330 -180
- package/lib/module/components/LottieIntroBlock/LottieIntroBlock.js +144 -0
- package/lib/module/components/PageHero/PageHero.js +147 -0
- package/lib/module/components/PoweredByLabel/PoweredByLabel.js +130 -0
- package/lib/module/components/PoweredByLabel/finvu.png +0 -0
- package/lib/module/components/Text/Text.js +9 -2
- package/lib/module/components/Tooltip/Tooltip.js +34 -27
- package/lib/module/components/index.js +7 -1
- package/lib/module/design-tokens/Coin Variables-variables-full.json +1 -1
- package/lib/module/icons/registry.js +1 -1
- package/lib/typescript/src/components/AccountCard/AccountCard.d.ts +81 -0
- package/lib/typescript/src/components/CardBankAccount/CardBankAccount.d.ts +9 -2
- package/lib/typescript/src/components/CheckboxItem/CheckboxItem.d.ts +18 -2
- package/lib/typescript/src/components/Dropdown/Dropdown.d.ts +62 -0
- package/lib/typescript/src/components/DropdownInput/DropdownInput.d.ts +107 -0
- package/lib/typescript/src/components/FormField/FormField.d.ts +76 -19
- package/lib/typescript/src/components/LottieIntroBlock/LottieIntroBlock.d.ts +58 -0
- package/lib/typescript/src/components/PageHero/PageHero.d.ts +53 -0
- package/lib/typescript/src/components/PoweredByLabel/PoweredByLabel.d.ts +70 -0
- package/lib/typescript/src/components/Text/Text.d.ts +12 -2
- package/lib/typescript/src/components/Tooltip/Tooltip.d.ts +13 -2
- package/lib/typescript/src/components/index.d.ts +7 -1
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -3
- package/src/components/AccountCard/AccountCard.tsx +376 -0
- package/src/components/AppBar/AppBar.tsx +25 -14
- package/src/components/CardBankAccount/CardBankAccount.tsx +29 -3
- package/src/components/CheckboxItem/CheckboxItem.tsx +65 -30
- package/src/components/Dropdown/Dropdown.tsx +331 -0
- package/src/components/DropdownInput/DropdownInput.tsx +819 -0
- package/src/components/FormField/FormField.tsx +542 -215
- package/src/components/LottieIntroBlock/LottieIntroBlock.tsx +202 -0
- package/src/components/PageHero/PageHero.tsx +200 -0
- package/src/components/PoweredByLabel/PoweredByLabel.tsx +221 -0
- package/src/components/PoweredByLabel/finvu.png +0 -0
- package/src/components/Text/Text.tsx +24 -3
- package/src/components/Tooltip/Tooltip.tsx +50 -25
- package/src/components/index.ts +15 -1
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/icons/registry.ts +1 -1
|
@@ -7,223 +7,373 @@ exports.default = void 0;
|
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
10
|
-
var _reactUtils = require("../../utils/react-utils");
|
|
11
10
|
var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
|
|
12
|
-
var
|
|
11
|
+
var _reactUtils = require("../../utils/react-utils");
|
|
13
12
|
var _SupportText = _interopRequireDefault(require("../SupportText/SupportText"));
|
|
13
|
+
var _Icon = _interopRequireDefault(require("../../icons/Icon"));
|
|
14
|
+
var _Form = require("../Form/Form");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
isDisabled = false,
|
|
21
|
-
isInvalid = false,
|
|
22
|
-
supportText,
|
|
23
|
-
errorMessage,
|
|
24
|
-
modes: propModes = _reactUtils.EMPTY_MODES,
|
|
25
|
-
onFocus,
|
|
26
|
-
onBlur
|
|
27
|
-
} = props;
|
|
28
|
-
const {
|
|
29
|
-
modes: globalModes
|
|
30
|
-
} = (0, _JFSThemeProvider.useTokens)();
|
|
31
|
-
const baseModes = (0, _react.useMemo)(() => ({
|
|
32
|
-
...globalModes,
|
|
33
|
-
...propModes
|
|
34
|
-
}), [globalModes, propModes]);
|
|
35
|
-
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Token resolution
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
36
21
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
22
|
+
function toNumber(value, fallback) {
|
|
23
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
24
|
+
if (typeof value === 'string') {
|
|
25
|
+
const parsed = parseFloat(value);
|
|
26
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
27
|
+
}
|
|
28
|
+
return fallback;
|
|
29
|
+
}
|
|
30
|
+
function toFontWeight(value, fallback) {
|
|
31
|
+
if (typeof value === 'number') return value.toString();
|
|
32
|
+
if (typeof value === 'string' && value.length > 0) return value;
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
function useFormFieldTokens(modes) {
|
|
36
|
+
return (0, _react.useMemo)(() => {
|
|
37
|
+
// Wrapper
|
|
38
|
+
const gap = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/gap', modes), 8);
|
|
39
|
+
|
|
40
|
+
// Label (Figma: 14/17 medium, color #0c0d10)
|
|
41
|
+
const labelColor = (0, _figmaVariablesResolver.getVariableByName)('formField/label/color', modes) || '#0c0d10';
|
|
42
|
+
const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('formField/label/fontFamily', modes) || 'JioType Var';
|
|
43
|
+
const labelFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/label/fontSize', modes), 14);
|
|
44
|
+
const labelLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/label/lineHeight', modes), 17);
|
|
45
|
+
const labelFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('formField/label/fontWeight', modes), '500');
|
|
46
|
+
|
|
47
|
+
// Input row (Figma: 12 px padding-h, 8 px gap, 8 px radius, 1 px border)
|
|
48
|
+
const inputPaddingH = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/input/padding/horizontal', modes), 12);
|
|
49
|
+
const inputGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/input/gap', modes), 8);
|
|
50
|
+
const inputRadius = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/input/radius', modes), 8);
|
|
51
|
+
const inputBorderSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/input/border/size', modes), 1);
|
|
52
|
+
|
|
53
|
+
// Input text (Figma: 16/45 regular)
|
|
54
|
+
const inputFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/input/label/fontSize', modes), 16);
|
|
55
|
+
const inputLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('formField/input/label/lineHeight', modes), 45);
|
|
56
|
+
const inputFontFamily = (0, _figmaVariablesResolver.getVariableByName)('formField/input/label/fontFamily', modes) || 'JioType Var';
|
|
57
|
+
const inputFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('formField/input/label/fontWeight', modes), '400');
|
|
58
|
+
const inputBackground = (0, _figmaVariablesResolver.getVariableByName)('formField/input/background', modes) || '#ffffff';
|
|
59
|
+
const inputBorderColor = (0, _figmaVariablesResolver.getVariableByName)('formField/input/border/color', modes) || '#b5b6b7';
|
|
60
|
+
if (__DEV__) {
|
|
61
|
+
console.warn('[FormField] border color (modes changed)', {
|
|
62
|
+
'FormField States': modes['FormField States'],
|
|
63
|
+
inputBorderColor,
|
|
64
|
+
'formField/input/border/color': (0, _figmaVariablesResolver.getVariableByName)('formField/input/border/color', modes)
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
const inputTextColor = (0, _figmaVariablesResolver.getVariableByName)('formField/input/label/color', modes) || '#24262b';
|
|
68
|
+
return {
|
|
69
|
+
gap,
|
|
70
|
+
labelColor,
|
|
71
|
+
labelFontFamily,
|
|
72
|
+
labelFontSize,
|
|
73
|
+
labelLineHeight,
|
|
74
|
+
labelFontWeight,
|
|
75
|
+
inputPaddingH,
|
|
76
|
+
inputGap,
|
|
77
|
+
inputRadius,
|
|
78
|
+
inputBorderSize,
|
|
79
|
+
inputFontSize,
|
|
80
|
+
inputLineHeight,
|
|
81
|
+
inputFontFamily,
|
|
82
|
+
inputFontWeight,
|
|
83
|
+
inputBackground,
|
|
84
|
+
inputBorderColor,
|
|
85
|
+
inputTextColor
|
|
86
|
+
};
|
|
87
|
+
}, [modes]);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Helpers
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
function deriveTypeProps(type) {
|
|
95
|
+
switch (type) {
|
|
96
|
+
case 'password':
|
|
97
|
+
return {
|
|
98
|
+
secureTextEntry: true,
|
|
99
|
+
keyboardType: 'default',
|
|
100
|
+
autoCapitalize: 'none',
|
|
101
|
+
autoComplete: 'password',
|
|
102
|
+
textContentType: 'password'
|
|
103
|
+
};
|
|
104
|
+
case 'email':
|
|
105
|
+
return {
|
|
106
|
+
secureTextEntry: false,
|
|
107
|
+
keyboardType: 'email-address',
|
|
108
|
+
autoCapitalize: 'none',
|
|
109
|
+
autoComplete: 'email',
|
|
110
|
+
textContentType: 'emailAddress'
|
|
111
|
+
};
|
|
112
|
+
case 'number':
|
|
113
|
+
return {
|
|
114
|
+
secureTextEntry: false,
|
|
115
|
+
keyboardType: 'numeric',
|
|
116
|
+
autoCapitalize: 'none',
|
|
117
|
+
autoComplete: 'off',
|
|
118
|
+
textContentType: 'none'
|
|
119
|
+
};
|
|
120
|
+
case 'phone':
|
|
121
|
+
return {
|
|
122
|
+
secureTextEntry: false,
|
|
123
|
+
keyboardType: 'phone-pad',
|
|
124
|
+
autoCapitalize: 'none',
|
|
125
|
+
autoComplete: 'tel',
|
|
126
|
+
textContentType: 'telephoneNumber'
|
|
127
|
+
};
|
|
128
|
+
case 'url':
|
|
129
|
+
return {
|
|
130
|
+
secureTextEntry: false,
|
|
131
|
+
keyboardType: 'url',
|
|
132
|
+
autoCapitalize: 'none',
|
|
133
|
+
autoComplete: 'url',
|
|
134
|
+
textContentType: 'URL'
|
|
135
|
+
};
|
|
136
|
+
case 'search':
|
|
137
|
+
return {
|
|
138
|
+
secureTextEntry: false,
|
|
139
|
+
keyboardType: 'default',
|
|
140
|
+
autoCapitalize: 'none',
|
|
141
|
+
autoComplete: 'off',
|
|
142
|
+
textContentType: 'none'
|
|
143
|
+
};
|
|
144
|
+
case 'text':
|
|
145
|
+
default:
|
|
146
|
+
return {
|
|
147
|
+
secureTextEntry: false,
|
|
148
|
+
keyboardType: 'default',
|
|
149
|
+
autoCapitalize: 'sentences',
|
|
150
|
+
autoComplete: 'off',
|
|
151
|
+
textContentType: 'none'
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function firstError(error) {
|
|
156
|
+
if (!error) return undefined;
|
|
157
|
+
if (Array.isArray(error)) return error[0];
|
|
158
|
+
return error;
|
|
135
159
|
}
|
|
160
|
+
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// Component
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
|
|
136
165
|
function FormField({
|
|
137
166
|
label,
|
|
138
167
|
placeholder,
|
|
139
|
-
value
|
|
168
|
+
value,
|
|
140
169
|
onChangeText,
|
|
141
170
|
type = 'text',
|
|
171
|
+
name,
|
|
142
172
|
leading,
|
|
143
173
|
trailing,
|
|
144
174
|
leadingIconName,
|
|
145
175
|
isRequired = false,
|
|
146
176
|
isDisabled = false,
|
|
147
177
|
isInvalid = false,
|
|
178
|
+
isReadOnly = false,
|
|
148
179
|
supportText,
|
|
149
180
|
errorMessage,
|
|
150
|
-
|
|
181
|
+
maxLength,
|
|
182
|
+
autoFocus = false,
|
|
183
|
+
modes: propModes = _reactUtils.EMPTY_MODES,
|
|
151
184
|
style,
|
|
185
|
+
inputStyle,
|
|
186
|
+
inputTextStyle,
|
|
152
187
|
onFocus,
|
|
153
188
|
onBlur,
|
|
189
|
+
onSubmitEditing,
|
|
154
190
|
accessibilityLabel,
|
|
155
|
-
accessibilityHint
|
|
191
|
+
accessibilityHint,
|
|
192
|
+
testID
|
|
156
193
|
}) {
|
|
194
|
+
// -- Form context integration -------------------------------------------
|
|
195
|
+
const formCtx = (0, _Form.useFormContext)();
|
|
196
|
+
const formError = name && formCtx ? firstError(formCtx.validationErrors[name]) : undefined;
|
|
197
|
+
const resolvedIsInvalid = isInvalid || Boolean(formError);
|
|
198
|
+
const resolvedErrorMessage = errorMessage ?? formError;
|
|
199
|
+
|
|
200
|
+
// -- Mode resolution ----------------------------------------------------
|
|
157
201
|
const {
|
|
158
|
-
modes:
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
202
|
+
modes: globalModes
|
|
203
|
+
} = (0, _JFSThemeProvider.useTokens)();
|
|
204
|
+
const baseModes = (0, _react.useMemo)(() => ({
|
|
205
|
+
...globalModes,
|
|
206
|
+
...propModes
|
|
207
|
+
}), [globalModes, propModes]);
|
|
208
|
+
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
209
|
+
const interactive = !isDisabled && !isReadOnly;
|
|
210
|
+
|
|
211
|
+
// FormField States cascade — error > read only/disabled > active (focused) > idle.
|
|
212
|
+
// Disabled maps to "Read Only" since there is no dedicated disabled mode and
|
|
213
|
+
// the visual treatment is closest. This is only the DEFAULT — an explicit
|
|
214
|
+
// `modes['FormField States']` passed in via props or the global theme
|
|
215
|
+
// always wins so consumers can force a state (e.g. for documentation).
|
|
216
|
+
const derivedStateMode = (0, _react.useMemo)(() => {
|
|
217
|
+
if (resolvedIsInvalid) return 'Error';
|
|
218
|
+
if (isReadOnly || isDisabled) return 'Read Only';
|
|
219
|
+
if (isFocused) return 'Active';
|
|
220
|
+
return 'Idle';
|
|
221
|
+
}, [resolvedIsInvalid, isReadOnly, isDisabled, isFocused]);
|
|
222
|
+
const modes = (0, _react.useMemo)(() => {
|
|
223
|
+
const explicitStateMode = baseModes['FormField States'];
|
|
224
|
+
const stateMode = explicitStateMode ?? derivedStateMode;
|
|
225
|
+
const explicitStatus = baseModes.Status;
|
|
226
|
+
// Default SupportText token mode is Auto (Figma resolves foreground from
|
|
227
|
+
// context). Pass modes={{ Status: 'Error' }} etc. to override.
|
|
228
|
+
const status = explicitStatus ?? 'Auto';
|
|
229
|
+
return {
|
|
230
|
+
...baseModes,
|
|
231
|
+
'FormField States': stateMode,
|
|
232
|
+
Status: status
|
|
233
|
+
};
|
|
234
|
+
}, [baseModes, derivedStateMode]);
|
|
235
|
+
const tokens = useFormFieldTokens(modes);
|
|
236
|
+
|
|
237
|
+
// -- Type-derived input props ------------------------------------------
|
|
238
|
+
const typeProps = (0, _react.useMemo)(() => deriveTypeProps(type), [type]);
|
|
239
|
+
|
|
240
|
+
// -- Event handlers ----------------------------------------------------
|
|
241
|
+
const handleFocus = (0, _react.useCallback)(e => {
|
|
242
|
+
setIsFocused(true);
|
|
243
|
+
onFocus?.(e);
|
|
244
|
+
}, [onFocus]);
|
|
245
|
+
const handleBlur = (0, _react.useCallback)(e => {
|
|
246
|
+
setIsFocused(false);
|
|
247
|
+
onBlur?.(e);
|
|
248
|
+
}, [onBlur]);
|
|
249
|
+
const handleChangeText = (0, _react.useCallback)(next => {
|
|
250
|
+
onChangeText?.(next);
|
|
251
|
+
if (name && formCtx) formCtx.onFieldChange(name);
|
|
252
|
+
}, [onChangeText, name, formCtx]);
|
|
253
|
+
|
|
254
|
+
// -- Styles ------------------------------------------------------------
|
|
255
|
+
const wrapperStyle = (0, _react.useMemo)(() => ({
|
|
256
|
+
gap: tokens.gap,
|
|
257
|
+
opacity: isDisabled ? 0.5 : 1
|
|
258
|
+
}), [tokens.gap, isDisabled]);
|
|
259
|
+
const labelRowStyle = (0, _react.useMemo)(() => ({
|
|
260
|
+
flexDirection: 'row',
|
|
261
|
+
alignItems: 'baseline'
|
|
262
|
+
}), []);
|
|
263
|
+
const labelTextStyle = (0, _react.useMemo)(() => ({
|
|
264
|
+
color: tokens.labelColor,
|
|
265
|
+
fontFamily: tokens.labelFontFamily,
|
|
266
|
+
fontSize: tokens.labelFontSize,
|
|
267
|
+
lineHeight: tokens.labelLineHeight,
|
|
268
|
+
fontWeight: tokens.labelFontWeight
|
|
269
|
+
}), [tokens.labelColor, tokens.labelFontFamily, tokens.labelFontSize, tokens.labelLineHeight, tokens.labelFontWeight]);
|
|
270
|
+
const requiredIndicatorStyle = (0, _react.useMemo)(() => ({
|
|
271
|
+
...labelTextStyle,
|
|
272
|
+
color: '#d93d3d'
|
|
273
|
+
}), [labelTextStyle]);
|
|
274
|
+
const inputRowStyle = (0, _react.useMemo)(() => ({
|
|
275
|
+
flexDirection: 'row',
|
|
276
|
+
alignItems: 'center',
|
|
277
|
+
backgroundColor: tokens.inputBackground,
|
|
278
|
+
borderColor: tokens.inputBorderColor,
|
|
279
|
+
borderWidth: tokens.inputBorderSize,
|
|
280
|
+
borderStyle: 'solid',
|
|
281
|
+
borderRadius: tokens.inputRadius,
|
|
282
|
+
paddingHorizontal: tokens.inputPaddingH,
|
|
283
|
+
paddingVertical: 0,
|
|
284
|
+
gap: tokens.inputGap,
|
|
285
|
+
minHeight: tokens.inputLineHeight,
|
|
286
|
+
width: '100%'
|
|
287
|
+
}), [tokens.inputBackground, tokens.inputBorderColor, tokens.inputBorderSize, tokens.inputRadius, tokens.inputPaddingH, tokens.inputGap, tokens.inputLineHeight]);
|
|
288
|
+
const inputTextStyles = (0, _react.useMemo)(() => ({
|
|
289
|
+
flex: 1,
|
|
290
|
+
color: tokens.inputTextColor,
|
|
291
|
+
fontFamily: tokens.inputFontFamily,
|
|
292
|
+
fontSize: tokens.inputFontSize,
|
|
293
|
+
lineHeight: tokens.inputLineHeight,
|
|
294
|
+
fontWeight: tokens.inputFontWeight,
|
|
295
|
+
padding: 0,
|
|
296
|
+
margin: 0,
|
|
297
|
+
// Remove the default web focus ring; the input row's border acts as the
|
|
298
|
+
// focus indicator via the FormField States cascade.
|
|
299
|
+
outlineStyle: 'none',
|
|
300
|
+
outlineWidth: 0,
|
|
301
|
+
outlineColor: 'transparent'
|
|
302
|
+
}), [tokens.inputTextColor, tokens.inputFontFamily, tokens.inputFontSize, tokens.inputLineHeight, tokens.inputFontWeight]);
|
|
303
|
+
const placeholderColor = (0, _react.useMemo)(() => {
|
|
304
|
+
// Slightly muted version of the resolved text color, mirroring the
|
|
305
|
+
// sibling TextInput behavior.
|
|
306
|
+
const c = tokens.inputTextColor;
|
|
307
|
+
if (typeof c !== 'string') return undefined;
|
|
308
|
+
if (c.startsWith('rgb(')) {
|
|
309
|
+
return c.replace('rgb(', 'rgba(').replace(')', ', 0.55)');
|
|
310
|
+
}
|
|
311
|
+
return '#888a8d';
|
|
312
|
+
}, [tokens.inputTextColor]);
|
|
313
|
+
|
|
314
|
+
// -- Slots --------------------------------------------------------------
|
|
315
|
+
const leadingElement = leading ?? (leadingIconName ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
|
|
316
|
+
name: leadingIconName,
|
|
317
|
+
size: 20,
|
|
318
|
+
color: tokens.inputTextColor
|
|
319
|
+
}) : null);
|
|
320
|
+
const processedLeading = leadingElement ? (0, _reactUtils.cloneChildrenWithModes)(leadingElement, modes) : null;
|
|
321
|
+
const processedTrailing = trailing ? (0, _reactUtils.cloneChildrenWithModes)(trailing, modes) : null;
|
|
322
|
+
|
|
323
|
+
// -- Support text -------------------------------------------------------
|
|
324
|
+
const supportStatus = resolvedIsInvalid ? 'Error' : 'Neutral';
|
|
325
|
+
const supportLabel = resolvedIsInvalid && resolvedErrorMessage ? resolvedErrorMessage : supportText;
|
|
326
|
+
|
|
327
|
+
// -- Accessibility ------------------------------------------------------
|
|
181
328
|
const resolvedA11yLabel = accessibilityLabel || label || placeholder || 'Form field';
|
|
182
329
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
183
330
|
style: [wrapperStyle, style],
|
|
184
331
|
pointerEvents: isDisabled ? 'none' : 'auto',
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
accessibilityLabel: resolvedA11yLabel,
|
|
188
|
-
accessibilityState: {
|
|
189
|
-
disabled: isDisabled
|
|
190
|
-
},
|
|
332
|
+
testID: testID,
|
|
333
|
+
accessible: false,
|
|
191
334
|
children: [label != null && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
192
|
-
style:
|
|
193
|
-
flexDirection: 'row',
|
|
194
|
-
alignItems: 'baseline'
|
|
195
|
-
},
|
|
335
|
+
style: labelRowStyle,
|
|
196
336
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
197
|
-
style:
|
|
337
|
+
style: labelTextStyle,
|
|
198
338
|
children: label
|
|
199
339
|
}), isRequired && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
200
340
|
style: requiredIndicatorStyle,
|
|
201
341
|
children: " *"
|
|
202
342
|
})]
|
|
203
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
343
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
344
|
+
style: [inputRowStyle, inputStyle],
|
|
345
|
+
children: [processedLeading != null && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
346
|
+
accessibilityElementsHidden: true,
|
|
347
|
+
importantForAccessibility: "no",
|
|
348
|
+
children: processedLeading
|
|
349
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
|
|
350
|
+
style: [inputTextStyles, inputTextStyle],
|
|
351
|
+
value: value ?? '',
|
|
352
|
+
onChangeText: handleChangeText,
|
|
353
|
+
onFocus: handleFocus,
|
|
354
|
+
onBlur: handleBlur,
|
|
355
|
+
onSubmitEditing: onSubmitEditing,
|
|
356
|
+
placeholder: placeholder ?? '',
|
|
357
|
+
placeholderTextColor: placeholderColor,
|
|
358
|
+
editable: interactive,
|
|
359
|
+
maxLength: maxLength,
|
|
360
|
+
autoFocus: autoFocus,
|
|
361
|
+
secureTextEntry: typeProps.secureTextEntry,
|
|
362
|
+
keyboardType: typeProps.keyboardType,
|
|
363
|
+
autoCapitalize: typeProps.autoCapitalize,
|
|
364
|
+
autoComplete: typeProps.autoComplete,
|
|
365
|
+
textContentType: typeProps.textContentType,
|
|
366
|
+
accessibilityLabel: resolvedA11yLabel,
|
|
367
|
+
accessibilityHint: accessibilityHint
|
|
368
|
+
}), processedTrailing != null && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
369
|
+
accessibilityElementsHidden: true,
|
|
370
|
+
importantForAccessibility: "no",
|
|
371
|
+
children: processedTrailing
|
|
372
|
+
})]
|
|
373
|
+
}), supportLabel != null && supportLabel !== '' && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SupportText.default, {
|
|
224
374
|
label: supportLabel,
|
|
225
375
|
status: supportStatus,
|
|
226
|
-
modes:
|
|
376
|
+
modes: modes
|
|
227
377
|
})]
|
|
228
378
|
});
|
|
229
379
|
}
|