jfs-components 0.0.77 → 0.0.78
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 +17 -0
- package/lib/commonjs/components/Accordion/Accordion.js +55 -55
- package/lib/commonjs/components/ActionFooter/ActionFooter.js +48 -2
- package/lib/commonjs/components/Checkbox/Checkbox.js +21 -9
- package/lib/commonjs/components/DropdownInput/DropdownInput.js +30 -16
- package/lib/commonjs/components/ExpandableCheckbox/ExpandableCheckbox.js +167 -0
- package/lib/commonjs/components/FormField/FormField.js +14 -1
- package/lib/commonjs/components/FullscreenModal/FullscreenModal.js +355 -0
- package/lib/commonjs/components/ListItem/ListItem.js +25 -10
- package/lib/commonjs/components/MessageField/MessageField.js +318 -0
- package/lib/commonjs/components/NavArrow/NavArrow.js +58 -17
- package/lib/commonjs/components/Stepper/Step.js +47 -60
- package/lib/commonjs/components/Stepper/StepLabel.js +40 -10
- package/lib/commonjs/components/Stepper/Stepper.js +15 -17
- package/lib/commonjs/components/SuggestiveSearch/SuggestiveSearch.js +487 -0
- package/lib/commonjs/components/TextInput/TextInput.js +16 -1
- package/lib/commonjs/components/Title/Title.js +10 -2
- package/lib/commonjs/components/index.js +28 -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/Accordion/Accordion.js +56 -56
- package/lib/module/components/ActionFooter/ActionFooter.js +50 -4
- package/lib/module/components/Checkbox/Checkbox.js +22 -10
- package/lib/module/components/DropdownInput/DropdownInput.js +30 -16
- package/lib/module/components/ExpandableCheckbox/ExpandableCheckbox.js +161 -0
- package/lib/module/components/FormField/FormField.js +16 -3
- package/lib/module/components/FullscreenModal/FullscreenModal.js +350 -0
- package/lib/module/components/ListItem/ListItem.js +25 -10
- package/lib/module/components/MessageField/MessageField.js +313 -0
- package/lib/module/components/NavArrow/NavArrow.js +59 -18
- package/lib/module/components/Stepper/Step.js +48 -61
- package/lib/module/components/Stepper/StepLabel.js +40 -10
- package/lib/module/components/Stepper/Stepper.js +15 -17
- package/lib/module/components/SuggestiveSearch/SuggestiveSearch.js +481 -0
- package/lib/module/components/TextInput/TextInput.js +17 -2
- package/lib/module/components/Title/Title.js +10 -2
- package/lib/module/components/index.js +4 -0
- 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/Accordion/Accordion.d.ts +14 -20
- package/lib/typescript/src/components/ExpandableCheckbox/ExpandableCheckbox.d.ts +63 -0
- package/lib/typescript/src/components/FullscreenModal/FullscreenModal.d.ts +99 -0
- package/lib/typescript/src/components/MessageField/MessageField.d.ts +81 -0
- package/lib/typescript/src/components/NavArrow/NavArrow.d.ts +10 -5
- package/lib/typescript/src/components/Stepper/Step.d.ts +4 -1
- package/lib/typescript/src/components/Stepper/StepLabel.d.ts +4 -1
- package/lib/typescript/src/components/Stepper/Stepper.d.ts +3 -1
- package/lib/typescript/src/components/SuggestiveSearch/SuggestiveSearch.d.ts +123 -0
- package/lib/typescript/src/components/index.d.ts +7 -3
- package/lib/typescript/src/icons/registry.d.ts +1 -1
- package/package.json +1 -1
- package/src/components/Accordion/Accordion.tsx +113 -73
- package/src/components/ActionFooter/ActionFooter.tsx +56 -4
- package/src/components/Checkbox/Checkbox.tsx +22 -9
- package/src/components/DropdownInput/DropdownInput.tsx +67 -39
- package/src/components/ExpandableCheckbox/ExpandableCheckbox.tsx +237 -0
- package/src/components/FormField/FormField.tsx +19 -3
- package/src/components/FullscreenModal/FullscreenModal.tsx +414 -0
- package/src/components/ListItem/ListItem.tsx +21 -10
- package/src/components/MessageField/MessageField.tsx +543 -0
- package/src/components/NavArrow/NavArrow.tsx +81 -17
- package/src/components/Stepper/Step.tsx +52 -51
- package/src/components/Stepper/StepLabel.tsx +46 -9
- package/src/components/Stepper/Stepper.tsx +20 -15
- package/src/components/SuggestiveSearch/SuggestiveSearch.tsx +756 -0
- package/src/components/TextInput/TextInput.tsx +14 -1
- package/src/components/Title/Title.tsx +13 -2
- package/src/components/index.ts +7 -3
- package/src/design-tokens/Coin Variables-variables-full.json +1 -1
- package/src/icons/registry.ts +1 -1
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
10
|
+
var _JFSThemeProvider = require("../../design-tokens/JFSThemeProvider");
|
|
11
|
+
var _reactUtils = require("../../utils/react-utils");
|
|
12
|
+
var _Form = require("../Form/Form");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
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); }
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Types
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Visual state of the textarea. Mirrors the `FormField States` collection so
|
|
21
|
+
* MessageField slots into the same theming pipeline as FormField. The state
|
|
22
|
+
* is always derived from props (`isInvalid`, `isDisabled`, `isReadOnly` and
|
|
23
|
+
* focus) and is locked in `modes['FormField States']` — passing that key in
|
|
24
|
+
* `modes` is intentionally ignored to keep interactive behaviour and visual
|
|
25
|
+
* state in sync.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Token helpers
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
function toNumber(value, fallback) {
|
|
33
|
+
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
34
|
+
if (typeof value === 'string') {
|
|
35
|
+
const parsed = parseFloat(value);
|
|
36
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
37
|
+
}
|
|
38
|
+
return fallback;
|
|
39
|
+
}
|
|
40
|
+
function toFontWeight(value, fallback) {
|
|
41
|
+
if (typeof value === 'number') return value.toString();
|
|
42
|
+
if (typeof value === 'string' && value.length > 0) return value;
|
|
43
|
+
return fallback;
|
|
44
|
+
}
|
|
45
|
+
function firstError(error) {
|
|
46
|
+
if (!error) return undefined;
|
|
47
|
+
if (Array.isArray(error)) return error[0];
|
|
48
|
+
return error;
|
|
49
|
+
}
|
|
50
|
+
function useMessageFieldTokens(modes) {
|
|
51
|
+
return (0, _react.useMemo)(() => {
|
|
52
|
+
const wrapperGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/gap', modes), 8);
|
|
53
|
+
const labelColor = (0, _figmaVariablesResolver.getVariableByName)('messageField/label/foreground', modes) || '#000000';
|
|
54
|
+
const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('messageField/label/fontFamily', modes) || 'JioType Var';
|
|
55
|
+
const labelFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/label/fontSize', modes), 14);
|
|
56
|
+
const labelLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/label/lineHeight', modes), 17);
|
|
57
|
+
const labelFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('messageField/label/fontWeight', modes), '500');
|
|
58
|
+
const textareaBackground = (0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/background', modes) || '#ffffff';
|
|
59
|
+
const textareaBorderColor = (0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/border/color', modes) || '#b5b6b7';
|
|
60
|
+
const textareaBorderSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/border/size', modes), 1.5);
|
|
61
|
+
const textareaRadius = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/radius', modes), 8);
|
|
62
|
+
const textareaPadding = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/padding', modes), 12);
|
|
63
|
+
const textareaHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/height', modes), 108);
|
|
64
|
+
const textareaGap = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/textarea/gap', modes), 0);
|
|
65
|
+
|
|
66
|
+
// `messageField/text/foreground` is the input text color. It also
|
|
67
|
+
// serves as the placeholder color — in mode-aware token sets it
|
|
68
|
+
// resolves to a muted/idle color when empty and shifts darker via
|
|
69
|
+
// the `FormField States` cascade once typed-state tokens land. We
|
|
70
|
+
// never re-route this through another token (e.g. the counter
|
|
71
|
+
// color) because that conflates two semantically distinct tokens.
|
|
72
|
+
const inputTextColor = (0, _figmaVariablesResolver.getVariableByName)('messageField/text/foreground', modes) || '#707275';
|
|
73
|
+
const inputFontFamily = (0, _figmaVariablesResolver.getVariableByName)('messageField/text/fontFamily', modes) || 'JioType Var';
|
|
74
|
+
const inputFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/text/fontSize', modes), 16);
|
|
75
|
+
const inputLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/text/lineHeight', modes), 21);
|
|
76
|
+
const inputFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('messageField/text/fontWeight', modes), '400');
|
|
77
|
+
const counterColor = (0, _figmaVariablesResolver.getVariableByName)('messageField/maxLength/foreground', modes) || '#24262b';
|
|
78
|
+
const counterFontFamily = (0, _figmaVariablesResolver.getVariableByName)('messageField/maxLength/fontFamily', modes) || 'JioType Var';
|
|
79
|
+
const counterFontSize = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/maxLength/fontSize', modes), 14);
|
|
80
|
+
const counterLineHeight = toNumber((0, _figmaVariablesResolver.getVariableByName)('messageField/maxLength/lineHeight', modes), 18);
|
|
81
|
+
const counterFontWeight = toFontWeight((0, _figmaVariablesResolver.getVariableByName)('messageField/maxLength/fontWeight', modes), '400');
|
|
82
|
+
return {
|
|
83
|
+
wrapperGap,
|
|
84
|
+
labelColor,
|
|
85
|
+
labelFontFamily,
|
|
86
|
+
labelFontSize,
|
|
87
|
+
labelLineHeight,
|
|
88
|
+
labelFontWeight,
|
|
89
|
+
textareaBackground,
|
|
90
|
+
textareaBorderColor,
|
|
91
|
+
textareaBorderSize,
|
|
92
|
+
textareaRadius,
|
|
93
|
+
textareaPadding,
|
|
94
|
+
textareaHeight,
|
|
95
|
+
textareaGap,
|
|
96
|
+
inputTextColor,
|
|
97
|
+
inputFontFamily,
|
|
98
|
+
inputFontSize,
|
|
99
|
+
inputLineHeight,
|
|
100
|
+
inputFontWeight,
|
|
101
|
+
counterColor,
|
|
102
|
+
counterFontFamily,
|
|
103
|
+
counterFontSize,
|
|
104
|
+
counterLineHeight,
|
|
105
|
+
counterFontWeight
|
|
106
|
+
};
|
|
107
|
+
}, [modes]);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// ---------------------------------------------------------------------------
|
|
111
|
+
// Component
|
|
112
|
+
// ---------------------------------------------------------------------------
|
|
113
|
+
|
|
114
|
+
const REQUIRED_INDICATOR_COLOR = '#d93d3d';
|
|
115
|
+
function MessageField({
|
|
116
|
+
label,
|
|
117
|
+
placeholder,
|
|
118
|
+
value,
|
|
119
|
+
defaultValue,
|
|
120
|
+
onChangeText,
|
|
121
|
+
name,
|
|
122
|
+
maxLength,
|
|
123
|
+
showCounter,
|
|
124
|
+
rows,
|
|
125
|
+
isRequired = false,
|
|
126
|
+
isDisabled = false,
|
|
127
|
+
isInvalid = false,
|
|
128
|
+
isReadOnly = false,
|
|
129
|
+
autoFocus = false,
|
|
130
|
+
modes: propModes = _reactUtils.EMPTY_MODES,
|
|
131
|
+
style,
|
|
132
|
+
textareaStyle,
|
|
133
|
+
inputStyle,
|
|
134
|
+
accessibilityLabel,
|
|
135
|
+
accessibilityHint,
|
|
136
|
+
testID,
|
|
137
|
+
onFocus,
|
|
138
|
+
onBlur
|
|
139
|
+
}) {
|
|
140
|
+
const formCtx = (0, _Form.useFormContext)();
|
|
141
|
+
const formError = name && formCtx ? firstError(formCtx.validationErrors[name]) : undefined;
|
|
142
|
+
const resolvedIsInvalid = isInvalid || Boolean(formError);
|
|
143
|
+
const isControlled = value !== undefined;
|
|
144
|
+
const [uncontrolledValue, setUncontrolledValue] = (0, _react.useState)(defaultValue ?? '');
|
|
145
|
+
const currentValue = isControlled ? value : uncontrolledValue;
|
|
146
|
+
const [isFocused, setIsFocused] = (0, _react.useState)(false);
|
|
147
|
+
const interactive = !isDisabled && !isReadOnly;
|
|
148
|
+
|
|
149
|
+
// Ref to the native textarea so tapping anywhere in the (padded) textarea
|
|
150
|
+
// container focuses it on the FIRST tap, fixing the Android "two taps to
|
|
151
|
+
// open the keyboard" issue.
|
|
152
|
+
const inputRef = (0, _react.useRef)(null);
|
|
153
|
+
const focusInput = (0, _react.useCallback)(() => {
|
|
154
|
+
if (!interactive) return;
|
|
155
|
+
inputRef.current?.focus();
|
|
156
|
+
}, [interactive]);
|
|
157
|
+
const {
|
|
158
|
+
modes: globalModes
|
|
159
|
+
} = (0, _JFSThemeProvider.useTokens)();
|
|
160
|
+
const baseModes = (0, _react.useMemo)(() => ({
|
|
161
|
+
...globalModes,
|
|
162
|
+
...propModes
|
|
163
|
+
}), [globalModes, propModes]);
|
|
164
|
+
|
|
165
|
+
// FormField States cascade — error > disabled > read only > active (focus)
|
|
166
|
+
// > idle. Always derived from props and locked into the modes object so
|
|
167
|
+
// consumers cannot pass `modes={{ 'FormField States': ... }}` and get out
|
|
168
|
+
// of sync with the component's actual interactive behaviour.
|
|
169
|
+
const stateMode = (0, _react.useMemo)(() => {
|
|
170
|
+
if (resolvedIsInvalid) return 'Error';
|
|
171
|
+
if (isDisabled) return 'Disabled';
|
|
172
|
+
if (isReadOnly) return 'Read Only';
|
|
173
|
+
if (isFocused) return 'Active';
|
|
174
|
+
return 'Idle';
|
|
175
|
+
}, [resolvedIsInvalid, isDisabled, isReadOnly, isFocused]);
|
|
176
|
+
const modes = (0, _react.useMemo)(() => ({
|
|
177
|
+
...baseModes,
|
|
178
|
+
'FormField States': stateMode
|
|
179
|
+
}), [baseModes, stateMode]);
|
|
180
|
+
const tokens = useMessageFieldTokens(modes);
|
|
181
|
+
|
|
182
|
+
// ---------- Event handlers ---------------------------------------------
|
|
183
|
+
const handleFocus = (0, _react.useCallback)(e => {
|
|
184
|
+
setIsFocused(true);
|
|
185
|
+
onFocus?.(e);
|
|
186
|
+
}, [onFocus]);
|
|
187
|
+
const handleBlur = (0, _react.useCallback)(e => {
|
|
188
|
+
setIsFocused(false);
|
|
189
|
+
onBlur?.(e);
|
|
190
|
+
}, [onBlur]);
|
|
191
|
+
const handleChangeText = (0, _react.useCallback)(next => {
|
|
192
|
+
if (!isControlled) {
|
|
193
|
+
setUncontrolledValue(next);
|
|
194
|
+
}
|
|
195
|
+
onChangeText?.(next);
|
|
196
|
+
if (name && formCtx) formCtx.onFieldChange(name);
|
|
197
|
+
}, [isControlled, onChangeText, name, formCtx]);
|
|
198
|
+
|
|
199
|
+
// ---------- Derived layout values --------------------------------------
|
|
200
|
+
const computedHeight = (0, _react.useMemo)(() => {
|
|
201
|
+
if (rows && rows > 0) {
|
|
202
|
+
return Math.round(rows * tokens.inputLineHeight + 2 * tokens.textareaPadding);
|
|
203
|
+
}
|
|
204
|
+
return tokens.textareaHeight;
|
|
205
|
+
}, [rows, tokens.inputLineHeight, tokens.textareaPadding, tokens.textareaHeight]);
|
|
206
|
+
const shouldShowCounter = (0, _react.useMemo)(() => {
|
|
207
|
+
if (showCounter === false) return false;
|
|
208
|
+
if (showCounter === true) return true;
|
|
209
|
+
return typeof maxLength === 'number';
|
|
210
|
+
}, [showCounter, maxLength]);
|
|
211
|
+
const counterText = (0, _react.useMemo)(() => {
|
|
212
|
+
const count = currentValue.length;
|
|
213
|
+
if (typeof maxLength === 'number') return `${count}/${maxLength}`;
|
|
214
|
+
return `${count}`;
|
|
215
|
+
}, [currentValue.length, maxLength]);
|
|
216
|
+
|
|
217
|
+
// ---------- Styles -----------------------------------------------------
|
|
218
|
+
const wrapperStyle = (0, _react.useMemo)(() => ({
|
|
219
|
+
gap: tokens.wrapperGap,
|
|
220
|
+
width: '100%'
|
|
221
|
+
}), [tokens.wrapperGap]);
|
|
222
|
+
const labelRowStyle = (0, _react.useMemo)(() => ({
|
|
223
|
+
flexDirection: 'row',
|
|
224
|
+
alignItems: 'baseline'
|
|
225
|
+
}), []);
|
|
226
|
+
const labelTextStyle = (0, _react.useMemo)(() => ({
|
|
227
|
+
color: tokens.labelColor,
|
|
228
|
+
fontFamily: tokens.labelFontFamily,
|
|
229
|
+
fontSize: tokens.labelFontSize,
|
|
230
|
+
lineHeight: tokens.labelLineHeight,
|
|
231
|
+
fontWeight: tokens.labelFontWeight
|
|
232
|
+
}), [tokens.labelColor, tokens.labelFontFamily, tokens.labelFontSize, tokens.labelLineHeight, tokens.labelFontWeight]);
|
|
233
|
+
const requiredIndicatorStyle = (0, _react.useMemo)(() => ({
|
|
234
|
+
...labelTextStyle,
|
|
235
|
+
color: REQUIRED_INDICATOR_COLOR
|
|
236
|
+
}), [labelTextStyle]);
|
|
237
|
+
const textareaContainerStyle = (0, _react.useMemo)(() => ({
|
|
238
|
+
backgroundColor: tokens.textareaBackground,
|
|
239
|
+
borderColor: tokens.textareaBorderColor,
|
|
240
|
+
borderWidth: tokens.textareaBorderSize,
|
|
241
|
+
borderStyle: 'solid',
|
|
242
|
+
borderRadius: tokens.textareaRadius,
|
|
243
|
+
padding: tokens.textareaPadding,
|
|
244
|
+
height: computedHeight,
|
|
245
|
+
width: '100%',
|
|
246
|
+
overflow: 'hidden',
|
|
247
|
+
// The gap token is for content within the textarea (icons, etc.);
|
|
248
|
+
// we keep it so downstream layouts that pass children align.
|
|
249
|
+
gap: tokens.textareaGap
|
|
250
|
+
}), [tokens.textareaBackground, tokens.textareaBorderColor, tokens.textareaBorderSize, tokens.textareaRadius, tokens.textareaPadding, computedHeight, tokens.textareaGap]);
|
|
251
|
+
const inputTextStyle = (0, _react.useMemo)(() => ({
|
|
252
|
+
flex: 1,
|
|
253
|
+
color: tokens.inputTextColor,
|
|
254
|
+
fontFamily: tokens.inputFontFamily,
|
|
255
|
+
fontSize: tokens.inputFontSize,
|
|
256
|
+
lineHeight: tokens.inputLineHeight,
|
|
257
|
+
fontWeight: tokens.inputFontWeight,
|
|
258
|
+
padding: 0,
|
|
259
|
+
margin: 0,
|
|
260
|
+
textAlignVertical: 'top',
|
|
261
|
+
// Disable the default web focus ring; the textarea border
|
|
262
|
+
// already encodes focus state.
|
|
263
|
+
outlineStyle: 'none',
|
|
264
|
+
outlineWidth: 0,
|
|
265
|
+
outlineColor: 'transparent'
|
|
266
|
+
}), [tokens.inputTextColor, tokens.inputFontFamily, tokens.inputFontSize, tokens.inputLineHeight, tokens.inputFontWeight]);
|
|
267
|
+
const counterTextStyle = (0, _react.useMemo)(() => ({
|
|
268
|
+
color: tokens.counterColor,
|
|
269
|
+
fontFamily: tokens.counterFontFamily,
|
|
270
|
+
fontSize: tokens.counterFontSize,
|
|
271
|
+
lineHeight: tokens.counterLineHeight,
|
|
272
|
+
fontWeight: tokens.counterFontWeight,
|
|
273
|
+
textAlign: 'right',
|
|
274
|
+
width: '100%'
|
|
275
|
+
}), [tokens.counterColor, tokens.counterFontFamily, tokens.counterFontSize, tokens.counterLineHeight, tokens.counterFontWeight]);
|
|
276
|
+
const resolvedA11yLabel = accessibilityLabel || label || placeholder || 'Message field';
|
|
277
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
278
|
+
style: [wrapperStyle, style],
|
|
279
|
+
pointerEvents: isDisabled ? 'none' : 'auto',
|
|
280
|
+
testID: testID,
|
|
281
|
+
accessible: false,
|
|
282
|
+
children: [label != null && label !== '' && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
283
|
+
style: labelRowStyle,
|
|
284
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
285
|
+
style: labelTextStyle,
|
|
286
|
+
children: label
|
|
287
|
+
}), isRequired && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
288
|
+
style: requiredIndicatorStyle,
|
|
289
|
+
children: " *"
|
|
290
|
+
})]
|
|
291
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
292
|
+
style: [textareaContainerStyle, textareaStyle],
|
|
293
|
+
onPress: focusInput,
|
|
294
|
+
accessible: false,
|
|
295
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
|
|
296
|
+
ref: inputRef,
|
|
297
|
+
multiline: true,
|
|
298
|
+
value: currentValue,
|
|
299
|
+
onChangeText: handleChangeText,
|
|
300
|
+
onFocus: handleFocus,
|
|
301
|
+
onBlur: handleBlur,
|
|
302
|
+
placeholder: placeholder ?? '',
|
|
303
|
+
placeholderTextColor: tokens.inputTextColor,
|
|
304
|
+
editable: interactive,
|
|
305
|
+
maxLength: maxLength,
|
|
306
|
+
autoFocus: autoFocus,
|
|
307
|
+
accessibilityLabel: resolvedA11yLabel,
|
|
308
|
+
accessibilityHint: accessibilityHint,
|
|
309
|
+
style: [inputTextStyle, inputStyle]
|
|
310
|
+
})
|
|
311
|
+
}), shouldShowCounter && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
312
|
+
style: counterTextStyle,
|
|
313
|
+
accessibilityElementsHidden: true,
|
|
314
|
+
children: counterText
|
|
315
|
+
})]
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
var _default = exports.default = MessageField;
|
|
@@ -8,9 +8,20 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _reactNativeSvg = _interopRequireWildcard(require("react-native-svg"));
|
|
10
10
|
var _figmaVariablesResolver = require("../../design-tokens/figma-variables-resolver");
|
|
11
|
+
var _webPlatformUtils = require("../../utils/web-platform-utils");
|
|
11
12
|
var _reactUtils = require("../../utils/react-utils");
|
|
12
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
14
|
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); }
|
|
15
|
+
/** Minimum touch target per iOS HIG / Material accessibility guidance. */
|
|
16
|
+
const MIN_TOUCH_TARGET = 44;
|
|
17
|
+
const IS_IOS = _reactNative.Platform.OS === 'ios';
|
|
18
|
+
const PRESS_DELAY = IS_IOS ? 130 : 0;
|
|
19
|
+
const touchTargetStyle = {
|
|
20
|
+
minWidth: MIN_TOUCH_TARGET,
|
|
21
|
+
minHeight: MIN_TOUCH_TARGET,
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
justifyContent: 'center'
|
|
24
|
+
};
|
|
14
25
|
function resolveNavArrowTokens(modes) {
|
|
15
26
|
const iconColor = (0, _figmaVariablesResolver.getVariableByName)('navArrow/icon/color', modes) || '#24262b';
|
|
16
27
|
const widthToken = Number((0, _figmaVariablesResolver.getVariableByName)('navArrow/width', modes)) || 6;
|
|
@@ -51,6 +62,8 @@ function NavArrow({
|
|
|
51
62
|
modes = _reactUtils.EMPTY_MODES,
|
|
52
63
|
style,
|
|
53
64
|
accessibilityLabel,
|
|
65
|
+
onPress,
|
|
66
|
+
disabled = false,
|
|
54
67
|
...rest
|
|
55
68
|
}) {
|
|
56
69
|
const tokens = (0, _react.useMemo)(() => resolveNavArrowTokens(modes), [modes]);
|
|
@@ -64,8 +77,7 @@ function NavArrow({
|
|
|
64
77
|
borderRadius: tokens.borderRadius,
|
|
65
78
|
backgroundColor: tokens.backgroundColor,
|
|
66
79
|
alignItems: 'center',
|
|
67
|
-
justifyContent: 'center'
|
|
68
|
-
...(style || {})
|
|
80
|
+
justifyContent: 'center'
|
|
69
81
|
};
|
|
70
82
|
const chevronW = isDown ? tokens.iconHeight : tokens.iconWidth;
|
|
71
83
|
const chevronH = isDown ? tokens.iconWidth : tokens.iconHeight;
|
|
@@ -91,26 +103,55 @@ function NavArrow({
|
|
|
91
103
|
svgHeight,
|
|
92
104
|
points
|
|
93
105
|
};
|
|
94
|
-
}, [tokens, direction
|
|
106
|
+
}, [tokens, direction]);
|
|
95
107
|
const defaultAccessibilityLabel = accessibilityLabel || (direction === 'Back' ? 'Go back' : direction === 'Forward' ? 'Go forward' : 'Go down');
|
|
108
|
+
const webProps = (0, _webPlatformUtils.usePressableWebSupport)({
|
|
109
|
+
restProps: rest,
|
|
110
|
+
onPress,
|
|
111
|
+
disabled,
|
|
112
|
+
accessibilityLabel: defaultAccessibilityLabel
|
|
113
|
+
});
|
|
114
|
+
const chevron = /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
|
|
115
|
+
width: computed.svgWidth,
|
|
116
|
+
height: computed.svgHeight,
|
|
117
|
+
viewBox: `0 0 ${computed.svgWidth} ${computed.svgHeight}`,
|
|
118
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Polyline, {
|
|
119
|
+
points: computed.points,
|
|
120
|
+
stroke: tokens.iconColor,
|
|
121
|
+
strokeWidth: tokens.strokeWeight,
|
|
122
|
+
strokeLinecap: "round",
|
|
123
|
+
strokeLinejoin: "round",
|
|
124
|
+
fill: "none"
|
|
125
|
+
})
|
|
126
|
+
});
|
|
127
|
+
if (onPress) {
|
|
128
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
129
|
+
onPress: onPress,
|
|
130
|
+
disabled: disabled,
|
|
131
|
+
accessibilityRole: "button",
|
|
132
|
+
accessibilityLabel: defaultAccessibilityLabel,
|
|
133
|
+
accessibilityState: {
|
|
134
|
+
disabled
|
|
135
|
+
},
|
|
136
|
+
unstable_pressDelay: PRESS_DELAY,
|
|
137
|
+
style: ({
|
|
138
|
+
pressed
|
|
139
|
+
}) => [touchTargetStyle, style, pressed && !disabled ? {
|
|
140
|
+
opacity: 0.7
|
|
141
|
+
} : null],
|
|
142
|
+
...webProps,
|
|
143
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
144
|
+
style: computed.containerStyle,
|
|
145
|
+
children: chevron
|
|
146
|
+
})
|
|
147
|
+
});
|
|
148
|
+
}
|
|
96
149
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
97
|
-
style: computed.containerStyle,
|
|
150
|
+
style: [computed.containerStyle, style],
|
|
98
151
|
accessibilityRole: "image",
|
|
99
152
|
accessibilityLabel: defaultAccessibilityLabel,
|
|
100
153
|
...rest,
|
|
101
|
-
children:
|
|
102
|
-
width: computed.svgWidth,
|
|
103
|
-
height: computed.svgHeight,
|
|
104
|
-
viewBox: `0 0 ${computed.svgWidth} ${computed.svgHeight}`,
|
|
105
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Polyline, {
|
|
106
|
-
points: computed.points,
|
|
107
|
-
stroke: tokens.iconColor,
|
|
108
|
-
strokeWidth: tokens.strokeWeight,
|
|
109
|
-
strokeLinecap: "round",
|
|
110
|
-
strokeLinejoin: "round",
|
|
111
|
-
fill: "none"
|
|
112
|
-
})
|
|
113
|
-
})
|
|
154
|
+
children: chevron
|
|
114
155
|
});
|
|
115
156
|
}
|
|
116
157
|
var _default = exports.default = /*#__PURE__*/_react.default.memo(NavArrow);
|
|
@@ -18,49 +18,45 @@ function Step({
|
|
|
18
18
|
modes = _reactUtils.EMPTY_MODES,
|
|
19
19
|
style,
|
|
20
20
|
index = 0,
|
|
21
|
+
showLine = true,
|
|
21
22
|
connectorStyle,
|
|
22
23
|
title,
|
|
23
24
|
supportingText,
|
|
25
|
+
metaText,
|
|
24
26
|
subtitle = true,
|
|
27
|
+
meta = true,
|
|
25
28
|
status = 'number'
|
|
26
29
|
}) {
|
|
27
|
-
// Container styles
|
|
28
30
|
const minHeight = Number((0, _figmaVariablesResolver.getVariableByName)('steperItem/minHeight', modes)) || 52;
|
|
29
|
-
const gap = Number((0, _figmaVariablesResolver.getVariableByName)('steperItem/gap', modes)) ||
|
|
30
|
-
|
|
31
|
-
// Indicator dimensions and styles
|
|
32
|
-
const indicatorSize = Number((0, _figmaVariablesResolver.getVariableByName)('stepIndicator/size', modes)) || 24;
|
|
31
|
+
const gap = Number((0, _figmaVariablesResolver.getVariableByName)('steperItem/gap', modes)) || 16;
|
|
32
|
+
const indicatorSize = Number((0, _figmaVariablesResolver.getVariableByName)('stepIndicator/size', modes)) || 36;
|
|
33
33
|
const indicatorRadius = Number((0, _figmaVariablesResolver.getVariableByName)('stepIndicator/radius', modes)) || 9999;
|
|
34
|
-
const indicatorBg = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/background', modes) || '#
|
|
35
|
-
const indicatorBorderColor = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/border/color', modes) || '#
|
|
34
|
+
const indicatorBg = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/background', modes) || '#5d00b5';
|
|
35
|
+
const indicatorBorderColor = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/border/color', modes) || '#5d00b5';
|
|
36
36
|
const indicatorBorderSize = Number((0, _figmaVariablesResolver.getVariableByName)('stepIndicator/border/size', modes)) || 1;
|
|
37
37
|
const iconColor = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/icon/color', modes) || '#ffffff';
|
|
38
|
-
|
|
39
|
-
// Label styles (for number)
|
|
38
|
+
const stepStatusSize = Number((0, _figmaVariablesResolver.getVariableByName)('stepStatus/size', modes)) || 18;
|
|
40
39
|
const labelFontSize = Number((0, _figmaVariablesResolver.getVariableByName)('stepIndicator/label/fontSize', modes)) || 12;
|
|
41
40
|
const labelFontFamily = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/label/fontFamily', modes) || undefined;
|
|
42
41
|
const labelLineHeight = Number((0, _figmaVariablesResolver.getVariableByName)('stepIndicator/label/lineHeight', modes)) || 14;
|
|
43
42
|
const labelFontWeight = (0, _figmaVariablesResolver.getVariableByName)('stepIndicator/label/fontWeight', modes) || '500';
|
|
44
|
-
|
|
45
|
-
// Vertical line styles
|
|
46
43
|
const lineSize = Number((0, _figmaVariablesResolver.getVariableByName)('steperItem/lineSize', modes)) || 2;
|
|
47
|
-
const lineColor = (0, _figmaVariablesResolver.getVariableByName)('steperItem/line', modes) || '#
|
|
44
|
+
const lineColor = (0, _figmaVariablesResolver.getVariableByName)('steperItem/line', modes) || '#5d00b5';
|
|
48
45
|
const badgeWrapGap = Number((0, _figmaVariablesResolver.getVariableByName)('steperItem/badgeWrap/gap', modes)) || 2;
|
|
49
46
|
const containerStyle = {
|
|
50
47
|
flexDirection: 'row',
|
|
51
48
|
minHeight,
|
|
49
|
+
gap,
|
|
52
50
|
...style
|
|
53
51
|
};
|
|
54
|
-
|
|
55
|
-
// FIX: This wrapper should NOT expand. It should be exact width of the indicator.
|
|
56
52
|
const indicatorWrapperStyle = {
|
|
57
53
|
flexDirection: 'column',
|
|
58
54
|
alignItems: 'center',
|
|
59
55
|
width: indicatorSize,
|
|
60
56
|
flexGrow: 0,
|
|
61
|
-
// Do NOT grow
|
|
62
57
|
flexShrink: 0,
|
|
63
|
-
gap: badgeWrapGap
|
|
58
|
+
gap: badgeWrapGap,
|
|
59
|
+
alignSelf: 'stretch'
|
|
64
60
|
};
|
|
65
61
|
const indicatorStyle = {
|
|
66
62
|
width: indicatorSize,
|
|
@@ -73,6 +69,12 @@ function Step({
|
|
|
73
69
|
justifyContent: 'center',
|
|
74
70
|
overflow: 'hidden'
|
|
75
71
|
};
|
|
72
|
+
const stepStatusContainerStyle = {
|
|
73
|
+
width: stepStatusSize,
|
|
74
|
+
height: stepStatusSize,
|
|
75
|
+
alignItems: 'center',
|
|
76
|
+
justifyContent: 'center'
|
|
77
|
+
};
|
|
76
78
|
const labelStyle = {
|
|
77
79
|
color: iconColor,
|
|
78
80
|
fontSize: labelFontSize,
|
|
@@ -81,24 +83,19 @@ function Step({
|
|
|
81
83
|
lineHeight: labelLineHeight,
|
|
82
84
|
textAlign: 'center'
|
|
83
85
|
};
|
|
84
|
-
|
|
85
|
-
// Combine base line style with injected connectorStyle
|
|
86
86
|
const lineStyle = {
|
|
87
87
|
width: lineSize,
|
|
88
88
|
backgroundColor: lineColor,
|
|
89
89
|
flexGrow: 1,
|
|
90
|
-
|
|
91
|
-
...connectorStyle
|
|
90
|
+
minHeight: 1,
|
|
91
|
+
...connectorStyle
|
|
92
92
|
};
|
|
93
|
-
|
|
94
|
-
// Helper for icons
|
|
95
93
|
const renderIcon = () => {
|
|
96
94
|
switch (status) {
|
|
97
95
|
case 'complete':
|
|
98
|
-
// Checkmark
|
|
99
96
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
|
|
100
|
-
width:
|
|
101
|
-
height:
|
|
97
|
+
width: stepStatusSize,
|
|
98
|
+
height: stepStatusSize,
|
|
102
99
|
viewBox: "0 0 24 24",
|
|
103
100
|
fill: "none",
|
|
104
101
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
|
|
@@ -110,10 +107,9 @@ function Step({
|
|
|
110
107
|
})
|
|
111
108
|
});
|
|
112
109
|
case 'error':
|
|
113
|
-
// X mark
|
|
114
110
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
|
|
115
|
-
width:
|
|
116
|
-
height:
|
|
111
|
+
width: stepStatusSize,
|
|
112
|
+
height: stepStatusSize,
|
|
117
113
|
viewBox: "0 0 24 24",
|
|
118
114
|
fill: "none",
|
|
119
115
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
|
|
@@ -125,10 +121,9 @@ function Step({
|
|
|
125
121
|
})
|
|
126
122
|
});
|
|
127
123
|
case 'warning':
|
|
128
|
-
// Exclamation / Triangle
|
|
129
124
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.default, {
|
|
130
|
-
width:
|
|
131
|
-
height:
|
|
125
|
+
width: stepStatusSize,
|
|
126
|
+
height: stepStatusSize,
|
|
132
127
|
viewBox: "0 0 24 24",
|
|
133
128
|
fill: "none",
|
|
134
129
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeSvg.Path, {
|
|
@@ -147,46 +142,38 @@ function Step({
|
|
|
147
142
|
});
|
|
148
143
|
}
|
|
149
144
|
};
|
|
150
|
-
|
|
151
|
-
// Clone children to pass modes if they are StepLabel
|
|
152
|
-
const childrenWithProps = _react.default.Children.map(children, child => {
|
|
153
|
-
if (/*#__PURE__*/_react.default.isValidElement(child)) {
|
|
154
|
-
return /*#__PURE__*/_react.default.cloneElement(child, {
|
|
155
|
-
modes
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
return child;
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
// Determine if we have content to pad
|
|
162
|
-
// Default padding bottom to 16 if line is shown, but also respect connectorStyle display
|
|
163
|
-
// If display is none, we probably don't want the padding bottom either.
|
|
164
|
-
const isLineHidden = connectorStyle?.display === 'none';
|
|
165
|
-
const contentPaddingBottom = isLineHidden ? 0 : 16;
|
|
145
|
+
const hasSlotChildren = _react.default.Children.count(children) > 0;
|
|
166
146
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
167
147
|
style: containerStyle,
|
|
168
148
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
169
149
|
style: indicatorWrapperStyle,
|
|
170
150
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
171
151
|
style: indicatorStyle,
|
|
172
|
-
children:
|
|
173
|
-
|
|
152
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
153
|
+
style: stepStatusContainerStyle,
|
|
154
|
+
children: renderIcon()
|
|
155
|
+
})
|
|
156
|
+
}), showLine ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
174
157
|
style: lineStyle
|
|
175
|
-
})]
|
|
176
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
177
|
-
style: {
|
|
178
|
-
width: gap
|
|
179
|
-
}
|
|
158
|
+
}) : null]
|
|
180
159
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
181
160
|
style: {
|
|
182
|
-
flex: 1
|
|
183
|
-
paddingBottom: contentPaddingBottom
|
|
161
|
+
flex: 1
|
|
184
162
|
},
|
|
185
|
-
children:
|
|
186
|
-
title
|
|
187
|
-
|
|
163
|
+
children: hasSlotChildren ? (0, _reactUtils.cloneChildrenWithModes)(children, modes) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_StepLabel.StepLabel, {
|
|
164
|
+
...(title !== undefined ? {
|
|
165
|
+
title
|
|
166
|
+
} : {}),
|
|
167
|
+
...(supportingText !== undefined ? {
|
|
168
|
+
supportingText
|
|
169
|
+
} : {}),
|
|
170
|
+
...(metaText !== undefined ? {
|
|
171
|
+
metaText
|
|
172
|
+
} : {}),
|
|
173
|
+
subtitle: subtitle,
|
|
174
|
+
meta: meta,
|
|
188
175
|
modes: modes
|
|
189
|
-
})
|
|
176
|
+
})
|
|
190
177
|
})]
|
|
191
178
|
});
|
|
192
179
|
}
|