@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1334507601 → 16.0.0-alpha.1444784746
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/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +64 -20
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +139 -39
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +147 -24
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +108 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +148 -1
- package/Components/ModalComponent/BottomSheetModalContent.tsx +95 -9
- package/Components/ModalComponent/SortableList.tsx +2 -3
- package/Components/ModalComponent/TextInputContent.tsx +27 -4
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +74 -1
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +14 -1
- package/Components/ModalComponent/showTextInput.ts +11 -2
- package/Components/OfflineHandler/__tests__/index.test.tsx +109 -0
- package/Components/OfflineHandler/index.tsx +42 -4
- package/Components/PlayerContainer/PlayerContainer.tsx +8 -1
- package/Components/Transitioner/AnimationManager.js +1 -1
- package/Components/Transitioner/Scene.tsx +4 -3
- package/Components/Transitioner/Transitioner.tsx +71 -33
- package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
- package/Components/VideoLive/LiveImageManager.ts +8 -2
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +5 -5
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
import { usePlugins } from "@applicaster/zapp-react-native-redux/hooks";
|
|
4
|
+
import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
6
5
|
import {
|
|
7
6
|
inflateString,
|
|
8
7
|
objectToReadableString,
|
|
@@ -40,12 +39,8 @@ export async function inflateUrl(url) {
|
|
|
40
39
|
|
|
41
40
|
export function LinkHandler(props: Props) {
|
|
42
41
|
const screenData = props?.screenData;
|
|
43
|
-
const plugins = usePlugins();
|
|
44
42
|
|
|
45
|
-
const ScreenPlugin =
|
|
46
|
-
WEBVIEW_SCREEN_IDENTIFIER,
|
|
47
|
-
plugins
|
|
48
|
-
);
|
|
43
|
+
const ScreenPlugin = getPluginByIdentifier(WEBVIEW_SCREEN_IDENTIFIER);
|
|
49
44
|
|
|
50
45
|
const Component =
|
|
51
46
|
R.path(["module", "Component"], ScreenPlugin) ||
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
|
|
1
|
+
import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
3
2
|
import { loggerLiveImageManager } from "../../../VideoLive/loggerHelper";
|
|
4
3
|
|
|
5
4
|
const { log_debug, log_error } = loggerLiveImageManager;
|
|
@@ -74,10 +73,9 @@ export async function executePreloadHooks({
|
|
|
74
73
|
let payload: any = entry;
|
|
75
74
|
|
|
76
75
|
let needsAbort = false;
|
|
77
|
-
const plugins = appStore.get("plugins");
|
|
78
76
|
|
|
79
77
|
for (const hookConfig of sortedHooks) {
|
|
80
|
-
const plugin =
|
|
78
|
+
const plugin = getPluginByIdentifier(hookConfig.identifier, true);
|
|
81
79
|
|
|
82
80
|
if (!plugin?.module) {
|
|
83
81
|
log_debug(
|
|
@@ -8,7 +8,7 @@ import Image from "../Image";
|
|
|
8
8
|
import { useTrackCurrentAutoScrollingElement } from "@applicaster/zapp-react-native-utils/reactHooks/autoscrolling/useTrackCurrentAutoScrollingElement";
|
|
9
9
|
import { useUIComponentContext } from "@applicaster/zapp-react-native-ui-components/Contexts/UIComponentContext";
|
|
10
10
|
import { getPropComponentType } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
11
|
-
import {
|
|
11
|
+
import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
|
|
12
12
|
import { useAccessibilityState } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
13
13
|
|
|
14
14
|
type LiveImageProps = {
|
|
@@ -249,9 +249,8 @@ const LiveImageComponent = (props: LiveImageProps) => {
|
|
|
249
249
|
getPlayerConfig(player_screen_id, actionIdentifier) ?? {};
|
|
250
250
|
|
|
251
251
|
const playableEntry = playerPluginId ? getPlayableEntry(item) : null;
|
|
252
|
-
const plugins = appStore.get("plugins");
|
|
253
252
|
|
|
254
|
-
const playerPlugin =
|
|
253
|
+
const playerPlugin = getPluginByIdentifier(playerPluginId);
|
|
255
254
|
|
|
256
255
|
const isShouldRender =
|
|
257
256
|
playerPlugin &&
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Modal Building Block — Header
|
|
3
3
|
*
|
|
4
|
-
* Single-file Expo Snack demo for the Header building block spec.
|
|
5
|
-
*
|
|
6
4
|
* Green (configurable): title, closeButton (enable + asset), actionButtons styling
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* (incl. Clear padding/radius for Variant 3 / section_header Studio keys)
|
|
6
|
+
* White (hardcoded): container gutters, action button slot enablement/actions,
|
|
7
|
+
* close dimensions, default action labels (overridable via HeaderData.clearLabel)
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
import React, { useCallback, useState } from "react";
|
|
@@ -94,6 +93,12 @@ export type ActionButtonsStyleConfiguration = {
|
|
|
94
93
|
iosLetterSpacing: number;
|
|
95
94
|
androidLetterSpacing: number;
|
|
96
95
|
textTransform: TextTransform;
|
|
96
|
+
/** Green Variant 3 fields — defaults match ACTION_BUTTON_LAYOUT_SPEC. */
|
|
97
|
+
paddingTop?: number;
|
|
98
|
+
paddingRight?: number;
|
|
99
|
+
paddingBottom?: number;
|
|
100
|
+
paddingLeft?: number;
|
|
101
|
+
cornerRadius?: number;
|
|
97
102
|
};
|
|
98
103
|
|
|
99
104
|
export type HeaderConfiguration = {
|
|
@@ -133,6 +138,11 @@ export const DEFAULT_ACTION_BUTTONS_STYLE_CONFIGURATION: ActionButtonsStyleConfi
|
|
|
133
138
|
iosLetterSpacing: 0,
|
|
134
139
|
androidLetterSpacing: 0,
|
|
135
140
|
textTransform: "default",
|
|
141
|
+
paddingTop: 6,
|
|
142
|
+
paddingRight: 10,
|
|
143
|
+
paddingBottom: 6,
|
|
144
|
+
paddingLeft: 10,
|
|
145
|
+
cornerRadius: 16,
|
|
136
146
|
};
|
|
137
147
|
|
|
138
148
|
// ---------------------------------------------------------------------------
|
|
@@ -141,6 +151,8 @@ export const DEFAULT_ACTION_BUTTONS_STYLE_CONFIGURATION: ActionButtonsStyleConfi
|
|
|
141
151
|
|
|
142
152
|
export type HeaderData = {
|
|
143
153
|
title: string;
|
|
154
|
+
/** Localization override for Clear; falls back to ACTION_LABELS.clear. */
|
|
155
|
+
clearLabel?: string;
|
|
144
156
|
};
|
|
145
157
|
|
|
146
158
|
export type AudioPlayerHeaderProps = {
|
|
@@ -437,6 +449,7 @@ type HeaderActionButtonProps = {
|
|
|
437
449
|
actionType: HeaderActionType;
|
|
438
450
|
configuration: ActionButtonsStyleConfiguration;
|
|
439
451
|
focused?: boolean;
|
|
452
|
+
label?: string;
|
|
440
453
|
onPress?: () => void;
|
|
441
454
|
};
|
|
442
455
|
|
|
@@ -444,8 +457,24 @@ function HeaderActionButton({
|
|
|
444
457
|
actionType,
|
|
445
458
|
configuration,
|
|
446
459
|
focused = false,
|
|
460
|
+
label,
|
|
447
461
|
onPress,
|
|
448
462
|
}: HeaderActionButtonProps) {
|
|
463
|
+
const paddingTop =
|
|
464
|
+
configuration.paddingTop ?? ACTION_BUTTON_LAYOUT_SPEC.paddingTop;
|
|
465
|
+
|
|
466
|
+
const paddingRight =
|
|
467
|
+
configuration.paddingRight ?? ACTION_BUTTON_LAYOUT_SPEC.paddingRight;
|
|
468
|
+
|
|
469
|
+
const paddingBottom =
|
|
470
|
+
configuration.paddingBottom ?? ACTION_BUTTON_LAYOUT_SPEC.paddingBottom;
|
|
471
|
+
|
|
472
|
+
const paddingLeft =
|
|
473
|
+
configuration.paddingLeft ?? ACTION_BUTTON_LAYOUT_SPEC.paddingLeft;
|
|
474
|
+
|
|
475
|
+
const cornerRadius =
|
|
476
|
+
configuration.cornerRadius ?? ACTION_BUTTON_LAYOUT_SPEC.cornerRadius;
|
|
477
|
+
|
|
449
478
|
return (
|
|
450
479
|
<Pressable
|
|
451
480
|
onPress={onPress}
|
|
@@ -454,11 +483,11 @@ function HeaderActionButton({
|
|
|
454
483
|
pressed || focused
|
|
455
484
|
? configuration.focusedBackgroundColor
|
|
456
485
|
: configuration.defaultBackgroundColor,
|
|
457
|
-
borderRadius:
|
|
458
|
-
paddingTop
|
|
459
|
-
paddingRight
|
|
460
|
-
paddingBottom
|
|
461
|
-
paddingLeft
|
|
486
|
+
borderRadius: cornerRadius,
|
|
487
|
+
paddingTop,
|
|
488
|
+
paddingRight,
|
|
489
|
+
paddingBottom,
|
|
490
|
+
paddingLeft,
|
|
462
491
|
})}
|
|
463
492
|
>
|
|
464
493
|
<Text
|
|
@@ -481,7 +510,7 @@ function HeaderActionButton({
|
|
|
481
510
|
}}
|
|
482
511
|
numberOfLines={1}
|
|
483
512
|
>
|
|
484
|
-
{ACTION_LABELS[actionType]}
|
|
513
|
+
{label || ACTION_LABELS[actionType]}
|
|
485
514
|
</Text>
|
|
486
515
|
</Pressable>
|
|
487
516
|
);
|
|
@@ -594,14 +623,20 @@ export function AudioPlayerHeader({
|
|
|
594
623
|
onClear,
|
|
595
624
|
}: AudioPlayerHeaderProps) {
|
|
596
625
|
const modalBlocksStyle = useModalBlocksStyle();
|
|
597
|
-
|
|
626
|
+
|
|
627
|
+
// Next Up section header uses sectionHeader — never Theme modal `header`,
|
|
628
|
+
// so the Queue title styles do not collide with the section title.
|
|
629
|
+
const styleBlock =
|
|
630
|
+
configuration.variant === "section"
|
|
631
|
+
? modalBlocksStyle?.sectionHeader
|
|
632
|
+
: modalBlocksStyle?.header;
|
|
598
633
|
|
|
599
634
|
const effectiveConfig = React.useMemo(() => {
|
|
600
|
-
return mergeHeaderConfiguration(configuration,
|
|
601
|
-
}, [configuration,
|
|
635
|
+
return mergeHeaderConfiguration(configuration, styleBlock);
|
|
636
|
+
}, [configuration, styleBlock]);
|
|
602
637
|
|
|
603
638
|
const { variant, title, closeButton, actionButtons } = effectiveConfig;
|
|
604
|
-
const { title: titleText } = data;
|
|
639
|
+
const { title: titleText, clearLabel } = data;
|
|
605
640
|
|
|
606
641
|
const container = CONTAINER_SPEC[variant];
|
|
607
642
|
const behavior = ACTION_BUTTONS_BEHAVIOR[variant];
|
|
@@ -612,16 +647,24 @@ export function AudioPlayerHeader({
|
|
|
612
647
|
behavior.sectionEnabled
|
|
613
648
|
);
|
|
614
649
|
|
|
615
|
-
const showTrailingAction =
|
|
616
|
-
behavior.trailing,
|
|
617
|
-
behavior.
|
|
618
|
-
|
|
650
|
+
const showTrailingAction =
|
|
651
|
+
shouldShowActionSlot(behavior.trailing, behavior.sectionEnabled) &&
|
|
652
|
+
(behavior.trailing.actionType !== "clear" || !!onClear);
|
|
653
|
+
|
|
654
|
+
const actionLabelFor = (actionType?: HeaderActionType) => {
|
|
655
|
+
if (actionType === "clear" && clearLabel) {
|
|
656
|
+
return clearLabel;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
return actionType ? ACTION_LABELS[actionType] : undefined;
|
|
660
|
+
};
|
|
619
661
|
|
|
620
662
|
const leadingContent = showLeadingAction ? (
|
|
621
663
|
<HeaderActionButton
|
|
622
|
-
actionType={behavior.leading.actionType}
|
|
664
|
+
actionType={behavior.leading.actionType as HeaderActionType}
|
|
623
665
|
configuration={actionButtons}
|
|
624
666
|
focused={focusedLeadingAction}
|
|
667
|
+
label={actionLabelFor(behavior.leading.actionType)}
|
|
625
668
|
onPress={onCancel}
|
|
626
669
|
/>
|
|
627
670
|
) : onBack ? (
|
|
@@ -630,9 +673,10 @@ export function AudioPlayerHeader({
|
|
|
630
673
|
|
|
631
674
|
const trailingContent = showTrailingAction ? (
|
|
632
675
|
<HeaderActionButton
|
|
633
|
-
actionType={behavior.trailing.actionType}
|
|
676
|
+
actionType={behavior.trailing.actionType as HeaderActionType}
|
|
634
677
|
configuration={actionButtons}
|
|
635
678
|
focused={focusedTrailingAction}
|
|
679
|
+
label={actionLabelFor(behavior.trailing.actionType)}
|
|
636
680
|
onPress={behavior.trailing.actionType === "done" ? onDone : onClear}
|
|
637
681
|
/>
|
|
638
682
|
) : closeButton.enabled && !isCenterAligned ? (
|
|
@@ -18,11 +18,42 @@ import {
|
|
|
18
18
|
View,
|
|
19
19
|
} from "react-native";
|
|
20
20
|
|
|
21
|
+
import { resolveDefaultAssetUri } from "@applicaster/zapp-react-native-utils/actionUtils";
|
|
22
|
+
|
|
21
23
|
const styles = StyleSheet.create({
|
|
22
24
|
column: {
|
|
23
25
|
alignItems: "center",
|
|
24
26
|
width: "100%",
|
|
25
27
|
},
|
|
28
|
+
validationMessage: {
|
|
29
|
+
flexDirection: "row",
|
|
30
|
+
alignItems: "center",
|
|
31
|
+
alignSelf: "center",
|
|
32
|
+
overflow: "hidden",
|
|
33
|
+
backgroundColor: "rgba(229,30,37,1.00)",
|
|
34
|
+
borderRadius: 100,
|
|
35
|
+
marginTop: 16,
|
|
36
|
+
paddingLeft: 8,
|
|
37
|
+
paddingRight: 12,
|
|
38
|
+
paddingTop: 8,
|
|
39
|
+
paddingBottom: 8,
|
|
40
|
+
gap: 8,
|
|
41
|
+
},
|
|
42
|
+
validationMessageIcon: {
|
|
43
|
+
width: 20,
|
|
44
|
+
height: 20,
|
|
45
|
+
alignSelf: "flex-start",
|
|
46
|
+
},
|
|
47
|
+
validationMessageText: {
|
|
48
|
+
color: "rgba(255,255,255,1.00)",
|
|
49
|
+
fontFamily: Platform.select({
|
|
50
|
+
ios: "GreycliffCF-Bold",
|
|
51
|
+
android: "Greycliff-Bold",
|
|
52
|
+
default: "Greycliff-Bold",
|
|
53
|
+
}),
|
|
54
|
+
fontSize: 13,
|
|
55
|
+
lineHeight: 20,
|
|
56
|
+
},
|
|
26
57
|
textInput: {
|
|
27
58
|
padding: 0,
|
|
28
59
|
margin: 0,
|
|
@@ -51,14 +82,22 @@ export type TextTransform =
|
|
|
51
82
|
|
|
52
83
|
export type TextAlignment = "left" | "center";
|
|
53
84
|
|
|
85
|
+
export type UnderlineConfiguration = {
|
|
86
|
+
focusedBorderColor: string;
|
|
87
|
+
borderColor: string;
|
|
88
|
+
/** Bottom underline height; 0 = none (pill search uses borderWidth instead) */
|
|
89
|
+
underlineHeight: number;
|
|
90
|
+
underlineMarginTop: number;
|
|
91
|
+
/** Radius of the underline bar itself (bottom border style). */
|
|
92
|
+
underlineCornerRadius: number;
|
|
93
|
+
};
|
|
94
|
+
|
|
54
95
|
export type BackgroundConfiguration = {
|
|
55
96
|
defaultColor: string;
|
|
56
97
|
focusedColor: string;
|
|
57
98
|
borderColor: string;
|
|
58
99
|
focusedBorderColor: string;
|
|
59
100
|
borderWidth: number;
|
|
60
|
-
/** Bottom underline height; 0 = none (pill search uses borderWidth instead) */
|
|
61
|
-
underlineHeight: number;
|
|
62
101
|
cornerRadius: number;
|
|
63
102
|
paddingTop: number;
|
|
64
103
|
paddingRight: number;
|
|
@@ -95,6 +134,9 @@ export type TextConfiguration = {
|
|
|
95
134
|
androidLetterSpacing: number;
|
|
96
135
|
textTransform: TextTransform;
|
|
97
136
|
alignment: TextAlignment;
|
|
137
|
+
/** Vertical spacing around the input text; drives the gap above the underline. */
|
|
138
|
+
marginTop: number;
|
|
139
|
+
marginBottom: number;
|
|
98
140
|
};
|
|
99
141
|
|
|
100
142
|
export type LeadingIconConfiguration = {
|
|
@@ -117,6 +159,7 @@ export type IconsConfiguration = {
|
|
|
117
159
|
};
|
|
118
160
|
|
|
119
161
|
export type InputConfiguration = {
|
|
162
|
+
underline: UnderlineConfiguration;
|
|
120
163
|
background: BackgroundConfiguration;
|
|
121
164
|
label: LabelConfiguration;
|
|
122
165
|
text: TextConfiguration;
|
|
@@ -129,7 +172,6 @@ export const DEFAULT_BACKGROUND_CONFIGURATION: BackgroundConfiguration = {
|
|
|
129
172
|
borderColor: "rgba(255, 255, 255, 0.55)",
|
|
130
173
|
focusedBorderColor: "rgba(255, 255, 255, 0.85)",
|
|
131
174
|
borderWidth: 1,
|
|
132
|
-
underlineHeight: 0,
|
|
133
175
|
cornerRadius: 24,
|
|
134
176
|
paddingTop: 10,
|
|
135
177
|
paddingRight: 10,
|
|
@@ -165,6 +207,8 @@ export const DEFAULT_TEXT_CONFIGURATION: TextConfiguration = {
|
|
|
165
207
|
androidLetterSpacing: 0,
|
|
166
208
|
textTransform: "default",
|
|
167
209
|
alignment: "left",
|
|
210
|
+
marginTop: 0,
|
|
211
|
+
marginBottom: 0,
|
|
168
212
|
};
|
|
169
213
|
|
|
170
214
|
export const DEFAULT_ICONS_CONFIGURATION: IconsConfiguration = {
|
|
@@ -180,8 +224,17 @@ export const DEFAULT_ICONS_CONFIGURATION: IconsConfiguration = {
|
|
|
180
224
|
},
|
|
181
225
|
};
|
|
182
226
|
|
|
227
|
+
export const DEFAULT_UNDERLINE_CONFIGURATION: UnderlineConfiguration = {
|
|
228
|
+
borderColor: "rgba(255, 255, 255, 0.55)",
|
|
229
|
+
focusedBorderColor: "rgba(255, 255, 255, 0.85)",
|
|
230
|
+
underlineHeight: 0,
|
|
231
|
+
underlineMarginTop: 0,
|
|
232
|
+
underlineCornerRadius: 0,
|
|
233
|
+
};
|
|
234
|
+
|
|
183
235
|
export const DEFAULT_INPUT_CONFIGURATION: InputConfiguration = {
|
|
184
236
|
background: DEFAULT_BACKGROUND_CONFIGURATION,
|
|
237
|
+
underline: DEFAULT_UNDERLINE_CONFIGURATION,
|
|
185
238
|
label: DEFAULT_LABEL_CONFIGURATION,
|
|
186
239
|
text: DEFAULT_TEXT_CONFIGURATION,
|
|
187
240
|
icons: DEFAULT_ICONS_CONFIGURATION,
|
|
@@ -203,6 +256,7 @@ export type ItemProps = {
|
|
|
203
256
|
value?: string;
|
|
204
257
|
focused?: boolean;
|
|
205
258
|
focusedClearButton?: boolean;
|
|
259
|
+
validationMessage?: string;
|
|
206
260
|
onChangeText?: (text: string) => void;
|
|
207
261
|
onClearPress?: () => void;
|
|
208
262
|
onFocus?: () => void;
|
|
@@ -243,7 +297,7 @@ function shouldShowLabel(label: LabelConfiguration, labelText?: string) {
|
|
|
243
297
|
}
|
|
244
298
|
|
|
245
299
|
function isUnderlineLayout(configuration: InputConfiguration) {
|
|
246
|
-
return configuration.
|
|
300
|
+
return configuration.underline.underlineHeight > 0;
|
|
247
301
|
}
|
|
248
302
|
|
|
249
303
|
// ---------------------------------------------------------------------------
|
|
@@ -323,7 +377,7 @@ function InputContainer({
|
|
|
323
377
|
}
|
|
324
378
|
|
|
325
379
|
type InputUnderlineProps = {
|
|
326
|
-
configuration:
|
|
380
|
+
configuration: UnderlineConfiguration;
|
|
327
381
|
focused: boolean;
|
|
328
382
|
};
|
|
329
383
|
|
|
@@ -337,7 +391,9 @@ function InputUnderline({ configuration, focused }: InputUnderlineProps) {
|
|
|
337
391
|
style={[
|
|
338
392
|
styles.underline,
|
|
339
393
|
{
|
|
394
|
+
marginTop: configuration.underlineMarginTop,
|
|
340
395
|
height: configuration.underlineHeight,
|
|
396
|
+
borderRadius: configuration.underlineCornerRadius,
|
|
341
397
|
backgroundColor: focused
|
|
342
398
|
? configuration.focusedBorderColor
|
|
343
399
|
: configuration.borderColor,
|
|
@@ -427,6 +483,8 @@ function InputField({
|
|
|
427
483
|
}),
|
|
428
484
|
textTransform: getTextTransformStyle(configuration.textTransform),
|
|
429
485
|
textAlign: configuration.alignment,
|
|
486
|
+
marginTop: configuration.marginTop,
|
|
487
|
+
marginBottom: configuration.marginBottom,
|
|
430
488
|
},
|
|
431
489
|
]}
|
|
432
490
|
/>
|
|
@@ -479,12 +537,13 @@ export function AudioPlayerInput({
|
|
|
479
537
|
value = "",
|
|
480
538
|
focused = false,
|
|
481
539
|
focusedClearButton = false,
|
|
540
|
+
validationMessage,
|
|
482
541
|
onChangeText,
|
|
483
542
|
onClearPress,
|
|
484
543
|
onFocus,
|
|
485
544
|
onBlur,
|
|
486
545
|
}: ItemProps) {
|
|
487
|
-
const { background, label, text, icons } = configuration;
|
|
546
|
+
const { background, label, text, icons, underline } = configuration;
|
|
488
547
|
const inputRef = useRef<TextInputRef>(null);
|
|
489
548
|
const underlineLayout = isUnderlineLayout(configuration);
|
|
490
549
|
const showLabel = shouldShowLabel(label, data.label);
|
|
@@ -545,21 +604,40 @@ export function AudioPlayerInput({
|
|
|
545
604
|
</>
|
|
546
605
|
) : null}
|
|
547
606
|
{underlineLayout ? (
|
|
548
|
-
<InputUnderline configuration={
|
|
607
|
+
<InputUnderline configuration={underline} focused={focused} />
|
|
549
608
|
) : null}
|
|
550
609
|
</InputContainer>
|
|
551
610
|
</Pressable>
|
|
552
611
|
);
|
|
553
612
|
|
|
554
|
-
if (!showLabel || !data.label) {
|
|
555
|
-
return inputRow;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
613
|
return (
|
|
559
614
|
<View style={styles.column}>
|
|
560
|
-
|
|
561
|
-
|
|
615
|
+
{showLabel && data.label ? (
|
|
616
|
+
<>
|
|
617
|
+
<InputLabel text={data.label} configuration={label} />
|
|
618
|
+
<View style={{ height: background.verticalGutter }} />
|
|
619
|
+
</>
|
|
620
|
+
) : null}
|
|
562
621
|
{inputRow}
|
|
622
|
+
{validationMessage ? (
|
|
623
|
+
<View style={styles.validationMessage} accessibilityRole="alert">
|
|
624
|
+
<Image
|
|
625
|
+
source={{
|
|
626
|
+
uri: resolveDefaultAssetUri(
|
|
627
|
+
require("../../../../assets/empty-Info.png")
|
|
628
|
+
),
|
|
629
|
+
}}
|
|
630
|
+
style={styles.validationMessageIcon}
|
|
631
|
+
/>
|
|
632
|
+
<Text
|
|
633
|
+
style={styles.validationMessageText}
|
|
634
|
+
numberOfLines={1}
|
|
635
|
+
ellipsizeMode="tail"
|
|
636
|
+
>
|
|
637
|
+
{validationMessage}
|
|
638
|
+
</Text>
|
|
639
|
+
</View>
|
|
640
|
+
) : null}
|
|
563
641
|
</View>
|
|
564
642
|
);
|
|
565
643
|
}
|
|
@@ -572,55 +650,77 @@ export function AudioPlayerInput({
|
|
|
572
650
|
export const VARIANT_SEARCH_INPUT: InputConfiguration =
|
|
573
651
|
DEFAULT_INPUT_CONFIGURATION;
|
|
574
652
|
|
|
575
|
-
/**
|
|
653
|
+
/**
|
|
654
|
+
* Name playlist — centered title + 32pt text over a rounded bottom underline.
|
|
655
|
+
*
|
|
656
|
+
* Values mirror the manifest configuration the
|
|
657
|
+
* `quick-brick-component-text-field` plugin renders from; the comment on each
|
|
658
|
+
* line names the reference key it comes from.
|
|
659
|
+
*/
|
|
576
660
|
export const VARIANT_NAME_PLAYLIST_INPUT: InputConfiguration = {
|
|
577
661
|
background: {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
662
|
+
// text_input_background_*_background_color
|
|
663
|
+
defaultColor: "rgba(30,30,30,0.00)",
|
|
664
|
+
focusedColor: "rgba(46,46,46,0.00)",
|
|
665
|
+
// text_input_style_border_*_border_color
|
|
666
|
+
borderColor: "rgba(255,255,255,0.25)",
|
|
667
|
+
focusedBorderColor: "rgba(255,255,255,1.00)",
|
|
668
|
+
// border_border_style is "bottom", so the box border is off and the
|
|
669
|
+
// underline below draws the border instead.
|
|
582
670
|
borderWidth: 0,
|
|
583
|
-
underlineHeight: 1,
|
|
584
671
|
cornerRadius: 0,
|
|
672
|
+
// text_input_style_input_padding_*
|
|
585
673
|
paddingTop: 0,
|
|
586
674
|
paddingRight: 0,
|
|
587
|
-
paddingBottom:
|
|
675
|
+
paddingBottom: 0,
|
|
588
676
|
paddingLeft: 0,
|
|
589
|
-
horizontalGutter: 0,
|
|
590
|
-
verticalGutter:
|
|
591
|
-
height: 0,
|
|
677
|
+
horizontalGutter: 0, // text_input_style_input_horizontal_gutter
|
|
678
|
+
verticalGutter: 0, // component_style_vertical_gutter
|
|
679
|
+
height: 0, // hug content
|
|
680
|
+
},
|
|
681
|
+
underline: {
|
|
682
|
+
borderColor: "rgba(255,255,255,0.25)",
|
|
683
|
+
focusedBorderColor: "rgba(255,255,255,1.00)",
|
|
684
|
+
underlineHeight: 2, // text_input_style_border_border_size
|
|
685
|
+
// The gap above the bar comes from the text's marginBottom, matching how
|
|
686
|
+
// the plugin applies `text_label_margin_bottom` to the input itself.
|
|
687
|
+
underlineMarginTop: 0,
|
|
688
|
+
underlineCornerRadius: 4, // ..._border_bottom_border_corner_radius
|
|
592
689
|
},
|
|
593
690
|
label: {
|
|
594
|
-
enabled: true,
|
|
595
|
-
fontColor: "rgba(
|
|
596
|
-
iosFontFamily: "
|
|
597
|
-
androidFontFamily: "
|
|
598
|
-
fontSize:
|
|
599
|
-
lineHeight:
|
|
600
|
-
iosLetterSpacing:
|
|
691
|
+
enabled: true, // title_enable
|
|
692
|
+
fontColor: "rgba(255,255,255,0.50)", // title_style_color
|
|
693
|
+
iosFontFamily: "GreycliffCF-Bold", // title_style_ios_font_family
|
|
694
|
+
androidFontFamily: "Greycliff-Bold", // title_style_android_font_family
|
|
695
|
+
fontSize: 14, // title_style_font_size
|
|
696
|
+
lineHeight: 32, // title_style_line_height
|
|
697
|
+
iosLetterSpacing: 0,
|
|
601
698
|
androidLetterSpacing: 0,
|
|
602
|
-
textTransform: "default",
|
|
699
|
+
textTransform: "default", // title_style_text_transform: "none"
|
|
603
700
|
},
|
|
604
701
|
text: {
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
702
|
+
// text_input_style_text_label_*
|
|
703
|
+
fontColor: "rgba(255,255,255,1.00)", // active_label_color
|
|
704
|
+
focusedFontColor: "rgba(255,255,255,1.00)",
|
|
705
|
+
placeholderColor: "rgba(255,255,255,0.50)", // placeholder_label_color
|
|
706
|
+
cursorColor: "rgba(249,183,72,1.00)", // text_input_style_cursor_cursor_color
|
|
707
|
+
iosFontFamily: "GreycliffCF-Bold",
|
|
708
|
+
androidFontFamily: "Greycliff-Bold",
|
|
611
709
|
fontSize: 32,
|
|
612
710
|
lineHeight: 40,
|
|
613
|
-
iosLetterSpacing:
|
|
711
|
+
iosLetterSpacing: 0,
|
|
614
712
|
androidLetterSpacing: 0,
|
|
615
713
|
textTransform: "default",
|
|
616
714
|
alignment: "center",
|
|
715
|
+
marginTop: 20, // text_label_margin_top
|
|
716
|
+
marginBottom: 20, // text_label_margin_bottom
|
|
617
717
|
},
|
|
618
718
|
icons: {
|
|
619
719
|
width: 20,
|
|
620
720
|
height: 20,
|
|
621
721
|
leadingIcon: { enabled: false },
|
|
622
722
|
trailingIcon: {
|
|
623
|
-
enabled: false,
|
|
723
|
+
enabled: false, // clear_button_enable
|
|
624
724
|
backgroundColor: "rgba(58, 58, 60, 1)",
|
|
625
725
|
focusedBackgroundColor: "rgba(72, 72, 74, 1)",
|
|
626
726
|
},
|