@applicaster/zapp-react-native-ui-components 16.0.0-rc.35 → 16.0.0-rc.36
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.
|
@@ -0,0 +1,671 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Modal Building Block — Input
|
|
3
|
+
*
|
|
4
|
+
* Green (configurable): background, label, text, icons
|
|
5
|
+
* White (hardcoded): default search / clear icon assets, clear button circle layout
|
|
6
|
+
*
|
|
7
|
+
* Variants (VARIANT_*) are preset configuration bundles — not a config field.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import React, { useRef } from "react";
|
|
11
|
+
import {
|
|
12
|
+
Image,
|
|
13
|
+
Platform,
|
|
14
|
+
Pressable,
|
|
15
|
+
StyleSheet,
|
|
16
|
+
Text,
|
|
17
|
+
TextInput,
|
|
18
|
+
View,
|
|
19
|
+
} from "react-native";
|
|
20
|
+
|
|
21
|
+
const styles = StyleSheet.create({
|
|
22
|
+
column: {
|
|
23
|
+
alignItems: "center",
|
|
24
|
+
width: "100%",
|
|
25
|
+
},
|
|
26
|
+
textInput: {
|
|
27
|
+
padding: 0,
|
|
28
|
+
margin: 0,
|
|
29
|
+
},
|
|
30
|
+
textInputRow: {
|
|
31
|
+
flex: 1,
|
|
32
|
+
},
|
|
33
|
+
clearButton: {
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
justifyContent: "center",
|
|
36
|
+
},
|
|
37
|
+
underline: {
|
|
38
|
+
alignSelf: "stretch",
|
|
39
|
+
},
|
|
40
|
+
demoScreen: {
|
|
41
|
+
flex: 1,
|
|
42
|
+
backgroundColor: "#1C1C1E",
|
|
43
|
+
paddingTop: 64,
|
|
44
|
+
paddingHorizontal: 16,
|
|
45
|
+
gap: 24,
|
|
46
|
+
},
|
|
47
|
+
demoHeading: {
|
|
48
|
+
color: "#FFFFFF",
|
|
49
|
+
fontSize: 20,
|
|
50
|
+
fontWeight: "600",
|
|
51
|
+
marginBottom: 8,
|
|
52
|
+
},
|
|
53
|
+
demoLabel: {
|
|
54
|
+
color: "#999999",
|
|
55
|
+
fontSize: 13,
|
|
56
|
+
marginTop: 8,
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Configuration (green / editable fields)
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
export type TextTransform =
|
|
65
|
+
| "default"
|
|
66
|
+
| "lowercase"
|
|
67
|
+
| "uppercase"
|
|
68
|
+
| "capitalize";
|
|
69
|
+
|
|
70
|
+
export type TextAlignment = "left" | "center";
|
|
71
|
+
|
|
72
|
+
export type BackgroundConfiguration = {
|
|
73
|
+
defaultColor: string;
|
|
74
|
+
focusedColor: string;
|
|
75
|
+
borderColor: string;
|
|
76
|
+
focusedBorderColor: string;
|
|
77
|
+
borderWidth: number;
|
|
78
|
+
/** Bottom underline height; 0 = none (pill search uses borderWidth instead) */
|
|
79
|
+
underlineHeight: number;
|
|
80
|
+
cornerRadius: number;
|
|
81
|
+
paddingTop: number;
|
|
82
|
+
paddingRight: number;
|
|
83
|
+
paddingBottom: number;
|
|
84
|
+
paddingLeft: number;
|
|
85
|
+
horizontalGutter: number;
|
|
86
|
+
verticalGutter: number;
|
|
87
|
+
/** Fixed height for pill layout; 0 = hug content (name / underline layout) */
|
|
88
|
+
height: number;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export type LabelConfiguration = {
|
|
92
|
+
enabled: boolean;
|
|
93
|
+
fontColor: string;
|
|
94
|
+
iosFontFamily: string;
|
|
95
|
+
androidFontFamily: string;
|
|
96
|
+
fontSize: number;
|
|
97
|
+
lineHeight: number;
|
|
98
|
+
iosLetterSpacing: number;
|
|
99
|
+
androidLetterSpacing: number;
|
|
100
|
+
textTransform: TextTransform;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export type TextConfiguration = {
|
|
104
|
+
fontColor: string;
|
|
105
|
+
focusedFontColor: string;
|
|
106
|
+
placeholderColor: string;
|
|
107
|
+
cursorColor: string;
|
|
108
|
+
iosFontFamily: string;
|
|
109
|
+
androidFontFamily: string;
|
|
110
|
+
fontSize: number;
|
|
111
|
+
lineHeight: number;
|
|
112
|
+
iosLetterSpacing: number;
|
|
113
|
+
androidLetterSpacing: number;
|
|
114
|
+
textTransform: TextTransform;
|
|
115
|
+
alignment: TextAlignment;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type LeadingIconConfiguration = {
|
|
119
|
+
enabled: boolean;
|
|
120
|
+
asset?: string;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export type TrailingIconConfiguration = {
|
|
124
|
+
enabled: boolean;
|
|
125
|
+
asset?: string;
|
|
126
|
+
backgroundColor: string;
|
|
127
|
+
focusedBackgroundColor: string;
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
export type IconsConfiguration = {
|
|
131
|
+
width: number;
|
|
132
|
+
height: number;
|
|
133
|
+
leadingIcon: LeadingIconConfiguration;
|
|
134
|
+
trailingIcon: TrailingIconConfiguration;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export type InputConfiguration = {
|
|
138
|
+
background: BackgroundConfiguration;
|
|
139
|
+
label: LabelConfiguration;
|
|
140
|
+
text: TextConfiguration;
|
|
141
|
+
icons: IconsConfiguration;
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const DEFAULT_BACKGROUND_CONFIGURATION: BackgroundConfiguration = {
|
|
145
|
+
defaultColor: "#000000",
|
|
146
|
+
focusedColor: "#000000",
|
|
147
|
+
borderColor: "rgba(255, 255, 255, 0.55)",
|
|
148
|
+
focusedBorderColor: "rgba(255, 255, 255, 0.85)",
|
|
149
|
+
borderWidth: 1,
|
|
150
|
+
underlineHeight: 0,
|
|
151
|
+
cornerRadius: 24,
|
|
152
|
+
paddingTop: 10,
|
|
153
|
+
paddingRight: 10,
|
|
154
|
+
paddingBottom: 10,
|
|
155
|
+
paddingLeft: 14,
|
|
156
|
+
horizontalGutter: 8,
|
|
157
|
+
verticalGutter: 0,
|
|
158
|
+
height: 44,
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
export const DEFAULT_LABEL_CONFIGURATION: LabelConfiguration = {
|
|
162
|
+
enabled: false,
|
|
163
|
+
fontColor: "rgba(142, 142, 147, 1)",
|
|
164
|
+
iosFontFamily: "SFProText-Regular",
|
|
165
|
+
androidFontFamily: "Roboto",
|
|
166
|
+
fontSize: 15,
|
|
167
|
+
lineHeight: 20,
|
|
168
|
+
iosLetterSpacing: -0.2,
|
|
169
|
+
androidLetterSpacing: 0,
|
|
170
|
+
textTransform: "default",
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
export const DEFAULT_TEXT_CONFIGURATION: TextConfiguration = {
|
|
174
|
+
fontColor: "#FFFFFF",
|
|
175
|
+
focusedFontColor: "#FFFFFF",
|
|
176
|
+
placeholderColor: "rgba(142, 142, 147, 1)",
|
|
177
|
+
cursorColor: "#FFFFFF",
|
|
178
|
+
iosFontFamily: "SFProText-Regular",
|
|
179
|
+
androidFontFamily: "Roboto",
|
|
180
|
+
fontSize: 15,
|
|
181
|
+
lineHeight: 20,
|
|
182
|
+
iosLetterSpacing: -0.2,
|
|
183
|
+
androidLetterSpacing: 0,
|
|
184
|
+
textTransform: "default",
|
|
185
|
+
alignment: "left",
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export const DEFAULT_ICONS_CONFIGURATION: IconsConfiguration = {
|
|
189
|
+
width: 20,
|
|
190
|
+
height: 20,
|
|
191
|
+
leadingIcon: {
|
|
192
|
+
enabled: true,
|
|
193
|
+
},
|
|
194
|
+
trailingIcon: {
|
|
195
|
+
enabled: true,
|
|
196
|
+
backgroundColor: "rgba(58, 58, 60, 1)",
|
|
197
|
+
focusedBackgroundColor: "rgba(72, 72, 74, 1)",
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const DEFAULT_INPUT_CONFIGURATION: InputConfiguration = {
|
|
202
|
+
background: DEFAULT_BACKGROUND_CONFIGURATION,
|
|
203
|
+
label: DEFAULT_LABEL_CONFIGURATION,
|
|
204
|
+
text: DEFAULT_TEXT_CONFIGURATION,
|
|
205
|
+
icons: DEFAULT_ICONS_CONFIGURATION,
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// ---------------------------------------------------------------------------
|
|
209
|
+
// Data (runtime / localization)
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
|
|
212
|
+
export type InputData = {
|
|
213
|
+
placeholder: string;
|
|
214
|
+
/** Top instructional label (e.g. "Name your playlist") */
|
|
215
|
+
label?: string;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export type ItemProps = {
|
|
219
|
+
configuration: InputConfiguration;
|
|
220
|
+
data: InputData;
|
|
221
|
+
value?: string;
|
|
222
|
+
focused?: boolean;
|
|
223
|
+
focusedClearButton?: boolean;
|
|
224
|
+
onChangeText?: (text: string) => void;
|
|
225
|
+
onClearPress?: () => void;
|
|
226
|
+
onFocus?: () => void;
|
|
227
|
+
onBlur?: () => void;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// Hardcoded (white fields)
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
|
|
234
|
+
const CLEAR_BUTTON_SPEC = {
|
|
235
|
+
width: 20,
|
|
236
|
+
height: 20,
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const DEFAULT_SEARCH_ICON_ASSET =
|
|
240
|
+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAr0lEQVR42mNgGAXkgnXrNrEAcT4Q7wTiB1C8EyrGQqnhXlAD/0PxayiG8UFyXpQYDjOoG4hVkORUoGIweS9yggXm8kg86iKRfMJCigX5MJcToRbmk3xSLNgJ1aRChFoVqNqdpFgA8vJrEtSDIv7BoLKA5pHE80imbTIlI6M9AmJ9WhUVjyi1BG9hBzIUyZLHZFlChCP0oYbDLNEbspbooVnCQktLaGMBUsKgjeEDBgBwWWj4ea9s3wAAAABJRU5ErkJggg==";
|
|
241
|
+
|
|
242
|
+
const DEFAULT_CLEAR_ICON_ASSET =
|
|
243
|
+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAPklEQVR42mNgGAWjYGiD/0BATXVkaabIcEKGUMVwXIZR1XB0Q2liOE1dThcf0DQOaJqKaJoP6JKTR8EoIAgADw5TrVXxxAIAAAAASUVORK5CYII=";
|
|
244
|
+
|
|
245
|
+
function getTextTransformStyle(
|
|
246
|
+
textTransform: TextTransform
|
|
247
|
+
): "none" | "lowercase" | "uppercase" | "capitalize" {
|
|
248
|
+
return textTransform === "default" ? "none" : textTransform;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function shouldShowLeadingIcon(leadingIcon: LeadingIconConfiguration) {
|
|
252
|
+
return leadingIcon.enabled;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function shouldShowTrailingIcon(trailingIcon: TrailingIconConfiguration) {
|
|
256
|
+
return trailingIcon.enabled;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function shouldShowLabel(label: LabelConfiguration, labelText?: string) {
|
|
260
|
+
return label.enabled && !!labelText;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function isUnderlineLayout(configuration: InputConfiguration) {
|
|
264
|
+
return configuration.background.underlineHeight > 0;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// Inner components
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
|
|
271
|
+
type InputLabelProps = {
|
|
272
|
+
text: string;
|
|
273
|
+
configuration: LabelConfiguration;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
function InputLabel({ text, configuration }: InputLabelProps) {
|
|
277
|
+
const letterSpacing =
|
|
278
|
+
Platform.OS === "ios"
|
|
279
|
+
? configuration.iosLetterSpacing
|
|
280
|
+
: configuration.androidLetterSpacing;
|
|
281
|
+
|
|
282
|
+
return (
|
|
283
|
+
<Text
|
|
284
|
+
style={{
|
|
285
|
+
color: configuration.fontColor,
|
|
286
|
+
fontSize: configuration.fontSize,
|
|
287
|
+
lineHeight: configuration.lineHeight,
|
|
288
|
+
letterSpacing,
|
|
289
|
+
fontFamily: Platform.select({
|
|
290
|
+
ios: configuration.iosFontFamily,
|
|
291
|
+
android: configuration.androidFontFamily,
|
|
292
|
+
default: configuration.androidFontFamily,
|
|
293
|
+
}),
|
|
294
|
+
textTransform: getTextTransformStyle(configuration.textTransform),
|
|
295
|
+
textAlign: "center",
|
|
296
|
+
}}
|
|
297
|
+
numberOfLines={1}
|
|
298
|
+
>
|
|
299
|
+
{text}
|
|
300
|
+
</Text>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
type InputContainerProps = {
|
|
305
|
+
configuration: BackgroundConfiguration;
|
|
306
|
+
focused: boolean;
|
|
307
|
+
underlineLayout: boolean;
|
|
308
|
+
children: React.ReactNode;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
function InputContainer({
|
|
312
|
+
configuration,
|
|
313
|
+
focused,
|
|
314
|
+
underlineLayout,
|
|
315
|
+
children,
|
|
316
|
+
}: InputContainerProps) {
|
|
317
|
+
return (
|
|
318
|
+
<View
|
|
319
|
+
style={{
|
|
320
|
+
flexDirection: underlineLayout ? "column" : "row",
|
|
321
|
+
alignItems: "center",
|
|
322
|
+
alignSelf: "stretch",
|
|
323
|
+
height: configuration.height > 0 ? configuration.height : undefined,
|
|
324
|
+
backgroundColor: focused
|
|
325
|
+
? configuration.focusedColor
|
|
326
|
+
: configuration.defaultColor,
|
|
327
|
+
borderColor: focused
|
|
328
|
+
? configuration.focusedBorderColor
|
|
329
|
+
: configuration.borderColor,
|
|
330
|
+
borderWidth: configuration.borderWidth,
|
|
331
|
+
borderRadius: configuration.cornerRadius,
|
|
332
|
+
paddingTop: configuration.paddingTop,
|
|
333
|
+
paddingRight: configuration.paddingRight,
|
|
334
|
+
paddingBottom: configuration.paddingBottom,
|
|
335
|
+
paddingLeft: configuration.paddingLeft,
|
|
336
|
+
}}
|
|
337
|
+
>
|
|
338
|
+
{children}
|
|
339
|
+
</View>
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
type InputUnderlineProps = {
|
|
344
|
+
configuration: BackgroundConfiguration;
|
|
345
|
+
focused: boolean;
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
function InputUnderline({ configuration, focused }: InputUnderlineProps) {
|
|
349
|
+
if (configuration.underlineHeight <= 0) {
|
|
350
|
+
return null;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return (
|
|
354
|
+
<View
|
|
355
|
+
style={[
|
|
356
|
+
styles.underline,
|
|
357
|
+
{
|
|
358
|
+
height: configuration.underlineHeight,
|
|
359
|
+
backgroundColor: focused
|
|
360
|
+
? configuration.focusedBorderColor
|
|
361
|
+
: configuration.borderColor,
|
|
362
|
+
},
|
|
363
|
+
]}
|
|
364
|
+
/>
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
type InputLeadingIconProps = {
|
|
369
|
+
icons: IconsConfiguration;
|
|
370
|
+
tintColor: string;
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
function InputLeadingIcon({ icons, tintColor }: InputLeadingIconProps) {
|
|
374
|
+
const asset = icons.leadingIcon.asset ?? DEFAULT_SEARCH_ICON_ASSET;
|
|
375
|
+
|
|
376
|
+
return (
|
|
377
|
+
<Image
|
|
378
|
+
source={{ uri: asset }}
|
|
379
|
+
style={{
|
|
380
|
+
width: icons.width,
|
|
381
|
+
height: icons.height,
|
|
382
|
+
tintColor,
|
|
383
|
+
}}
|
|
384
|
+
resizeMode="contain"
|
|
385
|
+
/>
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
type TextInputRef = React.ElementRef<typeof TextInput>;
|
|
390
|
+
|
|
391
|
+
type InputFieldProps = {
|
|
392
|
+
inputRef?: React.RefObject<TextInputRef>;
|
|
393
|
+
value: string;
|
|
394
|
+
placeholder: string;
|
|
395
|
+
configuration: TextConfiguration;
|
|
396
|
+
focused: boolean;
|
|
397
|
+
stretch: boolean;
|
|
398
|
+
onChangeText?: (text: string) => void;
|
|
399
|
+
onFocus?: () => void;
|
|
400
|
+
onBlur?: () => void;
|
|
401
|
+
};
|
|
402
|
+
|
|
403
|
+
function InputField({
|
|
404
|
+
inputRef,
|
|
405
|
+
value,
|
|
406
|
+
placeholder,
|
|
407
|
+
configuration,
|
|
408
|
+
focused,
|
|
409
|
+
stretch,
|
|
410
|
+
onChangeText,
|
|
411
|
+
onFocus,
|
|
412
|
+
onBlur,
|
|
413
|
+
}: InputFieldProps) {
|
|
414
|
+
const letterSpacing =
|
|
415
|
+
Platform.OS === "ios"
|
|
416
|
+
? configuration.iosLetterSpacing
|
|
417
|
+
: configuration.androidLetterSpacing;
|
|
418
|
+
|
|
419
|
+
return (
|
|
420
|
+
<TextInput
|
|
421
|
+
ref={inputRef}
|
|
422
|
+
value={value}
|
|
423
|
+
placeholder={placeholder}
|
|
424
|
+
placeholderTextColor={configuration.placeholderColor}
|
|
425
|
+
onChangeText={onChangeText}
|
|
426
|
+
onFocus={onFocus}
|
|
427
|
+
onBlur={onBlur}
|
|
428
|
+
showSoftInputOnFocus
|
|
429
|
+
selectionColor={configuration.cursorColor}
|
|
430
|
+
cursorColor={configuration.cursorColor}
|
|
431
|
+
style={[
|
|
432
|
+
styles.textInput,
|
|
433
|
+
stretch ? styles.textInputRow : { alignSelf: "stretch", width: "100%" },
|
|
434
|
+
{
|
|
435
|
+
color: focused
|
|
436
|
+
? configuration.focusedFontColor
|
|
437
|
+
: configuration.fontColor,
|
|
438
|
+
fontSize: configuration.fontSize,
|
|
439
|
+
lineHeight: configuration.lineHeight,
|
|
440
|
+
letterSpacing,
|
|
441
|
+
fontFamily: Platform.select({
|
|
442
|
+
ios: configuration.iosFontFamily,
|
|
443
|
+
android: configuration.androidFontFamily,
|
|
444
|
+
default: configuration.androidFontFamily,
|
|
445
|
+
}),
|
|
446
|
+
textTransform: getTextTransformStyle(configuration.textTransform),
|
|
447
|
+
textAlign: configuration.alignment,
|
|
448
|
+
},
|
|
449
|
+
]}
|
|
450
|
+
/>
|
|
451
|
+
);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
type InputClearButtonProps = {
|
|
455
|
+
icons: IconsConfiguration;
|
|
456
|
+
focused?: boolean;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
function InputClearButton({ icons, focused = false }: InputClearButtonProps) {
|
|
460
|
+
const { trailingIcon } = icons;
|
|
461
|
+
const asset = trailingIcon.asset ?? DEFAULT_CLEAR_ICON_ASSET;
|
|
462
|
+
|
|
463
|
+
return (
|
|
464
|
+
<View
|
|
465
|
+
style={[
|
|
466
|
+
styles.clearButton,
|
|
467
|
+
{
|
|
468
|
+
width: CLEAR_BUTTON_SPEC.width,
|
|
469
|
+
height: CLEAR_BUTTON_SPEC.height,
|
|
470
|
+
borderRadius: CLEAR_BUTTON_SPEC.width / 2,
|
|
471
|
+
backgroundColor: focused
|
|
472
|
+
? trailingIcon.focusedBackgroundColor
|
|
473
|
+
: trailingIcon.backgroundColor,
|
|
474
|
+
},
|
|
475
|
+
]}
|
|
476
|
+
>
|
|
477
|
+
<Image
|
|
478
|
+
source={{ uri: asset }}
|
|
479
|
+
style={{
|
|
480
|
+
width: CLEAR_BUTTON_SPEC.width * 0.55,
|
|
481
|
+
height: CLEAR_BUTTON_SPEC.height * 0.55,
|
|
482
|
+
tintColor: "#000000",
|
|
483
|
+
}}
|
|
484
|
+
resizeMode="contain"
|
|
485
|
+
/>
|
|
486
|
+
</View>
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// ---------------------------------------------------------------------------
|
|
491
|
+
// Item
|
|
492
|
+
// ---------------------------------------------------------------------------
|
|
493
|
+
|
|
494
|
+
export function AudioPlayerInput({
|
|
495
|
+
configuration,
|
|
496
|
+
data,
|
|
497
|
+
value = "",
|
|
498
|
+
focused = false,
|
|
499
|
+
focusedClearButton = false,
|
|
500
|
+
onChangeText,
|
|
501
|
+
onClearPress,
|
|
502
|
+
onFocus,
|
|
503
|
+
onBlur,
|
|
504
|
+
}: ItemProps) {
|
|
505
|
+
const { background, label, text, icons } = configuration;
|
|
506
|
+
const inputRef = useRef<TextInputRef>(null);
|
|
507
|
+
const underlineLayout = isUnderlineLayout(configuration);
|
|
508
|
+
const showLabel = shouldShowLabel(label, data.label);
|
|
509
|
+
const showLeading = shouldShowLeadingIcon(icons.leadingIcon);
|
|
510
|
+
const showTrailing = shouldShowTrailingIcon(icons.trailingIcon);
|
|
511
|
+
|
|
512
|
+
const focusInput = () => {
|
|
513
|
+
inputRef.current?.focus();
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
const clearButton = showTrailing ? (
|
|
517
|
+
<InputClearButton icons={icons} focused={focusedClearButton} />
|
|
518
|
+
) : null;
|
|
519
|
+
|
|
520
|
+
const field = (
|
|
521
|
+
<InputField
|
|
522
|
+
inputRef={inputRef}
|
|
523
|
+
value={value}
|
|
524
|
+
placeholder={data.placeholder}
|
|
525
|
+
configuration={text}
|
|
526
|
+
focused={focused}
|
|
527
|
+
stretch={!underlineLayout}
|
|
528
|
+
onChangeText={onChangeText}
|
|
529
|
+
onFocus={onFocus}
|
|
530
|
+
onBlur={onBlur}
|
|
531
|
+
/>
|
|
532
|
+
);
|
|
533
|
+
|
|
534
|
+
const inputRow = (
|
|
535
|
+
<Pressable onPress={focusInput} style={{ alignSelf: "stretch" }}>
|
|
536
|
+
<InputContainer
|
|
537
|
+
configuration={background}
|
|
538
|
+
focused={focused}
|
|
539
|
+
underlineLayout={underlineLayout}
|
|
540
|
+
>
|
|
541
|
+
{showLeading ? (
|
|
542
|
+
<>
|
|
543
|
+
<InputLeadingIcon icons={icons} tintColor={text.placeholderColor} />
|
|
544
|
+
<View style={{ width: background.horizontalGutter }} />
|
|
545
|
+
</>
|
|
546
|
+
) : null}
|
|
547
|
+
{field}
|
|
548
|
+
{clearButton ? (
|
|
549
|
+
<>
|
|
550
|
+
<View style={{ width: background.horizontalGutter }} />
|
|
551
|
+
{onClearPress ? (
|
|
552
|
+
<Pressable
|
|
553
|
+
onPress={(event) => {
|
|
554
|
+
event.stopPropagation?.();
|
|
555
|
+
onClearPress();
|
|
556
|
+
}}
|
|
557
|
+
>
|
|
558
|
+
{clearButton}
|
|
559
|
+
</Pressable>
|
|
560
|
+
) : (
|
|
561
|
+
clearButton
|
|
562
|
+
)}
|
|
563
|
+
</>
|
|
564
|
+
) : null}
|
|
565
|
+
{underlineLayout ? (
|
|
566
|
+
<InputUnderline configuration={background} focused={focused} />
|
|
567
|
+
) : null}
|
|
568
|
+
</InputContainer>
|
|
569
|
+
</Pressable>
|
|
570
|
+
);
|
|
571
|
+
|
|
572
|
+
if (!showLabel || !data.label) {
|
|
573
|
+
return inputRow;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return (
|
|
577
|
+
<View style={styles.column}>
|
|
578
|
+
<InputLabel text={data.label} configuration={label} />
|
|
579
|
+
<View style={{ height: background.verticalGutter }} />
|
|
580
|
+
{inputRow}
|
|
581
|
+
</View>
|
|
582
|
+
);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// ---------------------------------------------------------------------------
|
|
586
|
+
// Variant presets — collections of configuration keys (not a variant field)
|
|
587
|
+
// ---------------------------------------------------------------------------
|
|
588
|
+
|
|
589
|
+
/** Search pill — leading icon + clear button */
|
|
590
|
+
export const VARIANT_SEARCH_INPUT: InputConfiguration =
|
|
591
|
+
DEFAULT_INPUT_CONFIGURATION;
|
|
592
|
+
|
|
593
|
+
/** Name playlist — centered title + label + underline (screenshot) */
|
|
594
|
+
export const VARIANT_NAME_PLAYLIST_INPUT: InputConfiguration = {
|
|
595
|
+
background: {
|
|
596
|
+
defaultColor: "transparent",
|
|
597
|
+
focusedColor: "transparent",
|
|
598
|
+
borderColor: "rgba(255, 255, 255, 0.35)",
|
|
599
|
+
focusedBorderColor: "rgba(255, 255, 255, 0.55)",
|
|
600
|
+
borderWidth: 0,
|
|
601
|
+
underlineHeight: 1,
|
|
602
|
+
cornerRadius: 0,
|
|
603
|
+
paddingTop: 0,
|
|
604
|
+
paddingRight: 0,
|
|
605
|
+
paddingBottom: 10,
|
|
606
|
+
paddingLeft: 0,
|
|
607
|
+
horizontalGutter: 0,
|
|
608
|
+
verticalGutter: 16,
|
|
609
|
+
height: 0,
|
|
610
|
+
},
|
|
611
|
+
label: {
|
|
612
|
+
enabled: true,
|
|
613
|
+
fontColor: "rgba(142, 142, 147, 1)",
|
|
614
|
+
iosFontFamily: "SFProText-Regular",
|
|
615
|
+
androidFontFamily: "Roboto",
|
|
616
|
+
fontSize: 15,
|
|
617
|
+
lineHeight: 20,
|
|
618
|
+
iosLetterSpacing: -0.2,
|
|
619
|
+
androidLetterSpacing: 0,
|
|
620
|
+
textTransform: "default",
|
|
621
|
+
},
|
|
622
|
+
text: {
|
|
623
|
+
fontColor: "#FFFFFF",
|
|
624
|
+
focusedFontColor: "#FFFFFF",
|
|
625
|
+
placeholderColor: "rgba(142, 142, 147, 1)",
|
|
626
|
+
cursorColor: "#FFFFFF",
|
|
627
|
+
iosFontFamily: "SFProText-Bold",
|
|
628
|
+
androidFontFamily: "Roboto-Bold",
|
|
629
|
+
fontSize: 32,
|
|
630
|
+
lineHeight: 40,
|
|
631
|
+
iosLetterSpacing: -0.6,
|
|
632
|
+
androidLetterSpacing: 0,
|
|
633
|
+
textTransform: "default",
|
|
634
|
+
alignment: "center",
|
|
635
|
+
},
|
|
636
|
+
icons: {
|
|
637
|
+
width: 20,
|
|
638
|
+
height: 20,
|
|
639
|
+
leadingIcon: { enabled: false },
|
|
640
|
+
trailingIcon: {
|
|
641
|
+
enabled: false,
|
|
642
|
+
backgroundColor: "rgba(58, 58, 60, 1)",
|
|
643
|
+
focusedBackgroundColor: "rgba(72, 72, 74, 1)",
|
|
644
|
+
},
|
|
645
|
+
},
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
/** Text only search pill — no leading icon */
|
|
649
|
+
export const VARIANT_TEXT_ONLY_INPUT: InputConfiguration = {
|
|
650
|
+
background: DEFAULT_BACKGROUND_CONFIGURATION,
|
|
651
|
+
label: DEFAULT_LABEL_CONFIGURATION,
|
|
652
|
+
text: DEFAULT_TEXT_CONFIGURATION,
|
|
653
|
+
icons: {
|
|
654
|
+
...DEFAULT_ICONS_CONFIGURATION,
|
|
655
|
+
leadingIcon: { enabled: false },
|
|
656
|
+
},
|
|
657
|
+
};
|
|
658
|
+
|
|
659
|
+
/** Search without clear button */
|
|
660
|
+
export const VARIANT_SEARCH_WITHOUT_CLEAR: InputConfiguration = {
|
|
661
|
+
background: DEFAULT_BACKGROUND_CONFIGURATION,
|
|
662
|
+
label: DEFAULT_LABEL_CONFIGURATION,
|
|
663
|
+
text: DEFAULT_TEXT_CONFIGURATION,
|
|
664
|
+
icons: {
|
|
665
|
+
...DEFAULT_ICONS_CONFIGURATION,
|
|
666
|
+
trailingIcon: {
|
|
667
|
+
...DEFAULT_ICONS_CONFIGURATION.trailingIcon,
|
|
668
|
+
enabled: false,
|
|
669
|
+
},
|
|
670
|
+
},
|
|
671
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "16.0.0-rc.
|
|
3
|
+
"version": "16.0.0-rc.36",
|
|
4
4
|
"description": "Applicaster Zapp React Native ui components for the Quick Brick App",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
},
|
|
29
29
|
"homepage": "https://github.com/applicaster/quickbrick#readme",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@applicaster/applicaster-types": "16.0.0-rc.
|
|
32
|
-
"@applicaster/zapp-react-native-bridge": "16.0.0-rc.
|
|
33
|
-
"@applicaster/zapp-react-native-redux": "16.0.0-rc.
|
|
34
|
-
"@applicaster/zapp-react-native-utils": "16.0.0-rc.
|
|
31
|
+
"@applicaster/applicaster-types": "16.0.0-rc.36",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "16.0.0-rc.36",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "16.0.0-rc.36",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "16.0.0-rc.36",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"url": "^0.11.0",
|