@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.
Files changed (26) hide show
  1. package/Components/LinkHandler/LinkHandler.tsx +2 -7
  2. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
  3. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
  4. package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +64 -20
  5. package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +139 -39
  6. package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +147 -24
  7. package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
  8. package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +108 -0
  9. package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +148 -1
  10. package/Components/ModalComponent/BottomSheetModalContent.tsx +95 -9
  11. package/Components/ModalComponent/SortableList.tsx +2 -3
  12. package/Components/ModalComponent/TextInputContent.tsx +27 -4
  13. package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +74 -1
  14. package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +14 -1
  15. package/Components/ModalComponent/showTextInput.ts +11 -2
  16. package/Components/OfflineHandler/__tests__/index.test.tsx +109 -0
  17. package/Components/OfflineHandler/index.tsx +42 -4
  18. package/Components/PlayerContainer/PlayerContainer.tsx +8 -1
  19. package/Components/Transitioner/AnimationManager.js +1 -1
  20. package/Components/Transitioner/Scene.tsx +4 -3
  21. package/Components/Transitioner/Transitioner.tsx +71 -33
  22. package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
  23. package/Components/VideoLive/LiveImageManager.ts +8 -2
  24. package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
  25. package/assets/empty-Info.png +0 -0
  26. 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 { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
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 = findPluginByIdentifier(
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 { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
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 = findPluginByIdentifier(hookConfig.identifier, plugins, true);
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 { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
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 = findPluginByIdentifier(playerPluginId, plugins);
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
- * White (hardcoded): container, action button layout/enable/actions, close dimensions,
8
- * action button padding/radius, action labels
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: ACTION_BUTTON_LAYOUT_SPEC.cornerRadius,
458
- paddingTop: ACTION_BUTTON_LAYOUT_SPEC.paddingTop,
459
- paddingRight: ACTION_BUTTON_LAYOUT_SPEC.paddingRight,
460
- paddingBottom: ACTION_BUTTON_LAYOUT_SPEC.paddingBottom,
461
- paddingLeft: ACTION_BUTTON_LAYOUT_SPEC.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
- const headerBlock = modalBlocksStyle?.header;
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, headerBlock);
601
- }, [configuration, headerBlock]);
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 = shouldShowActionSlot(
616
- behavior.trailing,
617
- behavior.sectionEnabled
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.background.underlineHeight > 0;
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: BackgroundConfiguration;
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={background} focused={focused} />
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
- <InputLabel text={data.label} configuration={label} />
561
- <View style={{ height: background.verticalGutter }} />
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
- /** Name playlist — centered title + label + underline (screenshot) */
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
- defaultColor: "transparent",
579
- focusedColor: "transparent",
580
- borderColor: "rgba(255, 255, 255, 0.35)",
581
- focusedBorderColor: "rgba(255, 255, 255, 0.55)",
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: 10,
675
+ paddingBottom: 0,
588
676
  paddingLeft: 0,
589
- horizontalGutter: 0,
590
- verticalGutter: 16,
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(142, 142, 147, 1)",
596
- iosFontFamily: "SFProText-Regular",
597
- androidFontFamily: "Roboto",
598
- fontSize: 15,
599
- lineHeight: 20,
600
- iosLetterSpacing: -0.2,
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
- fontColor: "#FFFFFF",
606
- focusedFontColor: "#FFFFFF",
607
- placeholderColor: "rgba(142, 142, 147, 1)",
608
- cursorColor: "#FFFFFF",
609
- iosFontFamily: "SFProText-Bold",
610
- androidFontFamily: "Roboto-Bold",
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: -0.6,
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
  },