@applicaster/zapp-react-native-ui-components 15.1.13-alpha.1034774223 → 15.1.13

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 (40) hide show
  1. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +1 -0
  2. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -0
  3. package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +87 -33
  4. package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +74 -57
  5. package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +107 -142
  6. package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +159 -410
  7. package/Components/ModalComponent/AudioPlayer/Components/index.ts +4 -8
  8. package/Components/ModalComponent/BottomSheetModalContent.tsx +61 -379
  9. package/Components/ModalComponent/Button/index.tsx +3 -5
  10. package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
  11. package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
  12. package/Components/ModalComponent/Header/index.tsx +7 -20
  13. package/Components/ModalComponent/Header/utils.ts +1 -1
  14. package/Components/ModalComponent/index.tsx +0 -11
  15. package/Components/ModalComponent/utils.ts +21 -82
  16. package/package.json +5 -6
  17. package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +0 -54
  18. package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +0 -21
  19. package/Components/ModalComponent/ActionsBottomSheet/index.ts +0 -9
  20. package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +0 -58
  21. package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +0 -653
  22. package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +0 -89
  23. package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +0 -230
  24. package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +0 -332
  25. package/Components/ModalComponent/ModalBlocksStyleContext.tsx +0 -10
  26. package/Components/ModalComponent/SortableList.tsx +0 -142
  27. package/Components/ModalComponent/SortableList.web.tsx +0 -102
  28. package/Components/ModalComponent/TextInputContent.tsx +0 -100
  29. package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +0 -238
  30. package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +0 -120
  31. package/Components/ModalComponent/__tests__/showTextInput.test.ts +0 -95
  32. package/Components/ModalComponent/presets/__tests__/getCell.test.ts +0 -66
  33. package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +0 -78
  34. package/Components/ModalComponent/presets/index.ts +0 -27
  35. package/Components/ModalComponent/presets/selectableCell.tsx +0 -28
  36. package/Components/ModalComponent/presets/standardCell.tsx +0 -41
  37. package/Components/ModalComponent/presets/types.ts +0 -35
  38. package/Components/ModalComponent/showTextInput.ts +0 -43
  39. package/Hooks/useEntryActionsExpander.ts +0 -63
  40. /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.tsx → Hero.js} +0 -0
@@ -9,8 +9,7 @@
9
9
  */
10
10
 
11
11
  import React, { useCallback, useState } from "react";
12
- import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
13
- import { isApplePlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
12
+ import { Image, Platform, StyleSheet, Text, View } from "react-native";
14
13
 
15
14
  const styles = StyleSheet.create({
16
15
  row: {
@@ -46,6 +45,29 @@ const styles = StyleSheet.create({
46
45
  alignItems: "center",
47
46
  justifyContent: "center",
48
47
  },
48
+ demoScreen: {
49
+ flex: 1,
50
+ backgroundColor: "#1C1C1E",
51
+ paddingTop: 64,
52
+ paddingHorizontal: 0,
53
+ gap: 24,
54
+ },
55
+ demoBlock: {
56
+ gap: 8,
57
+ paddingHorizontal: 0,
58
+ },
59
+ demoHeading: {
60
+ color: "#FFFFFF",
61
+ fontSize: 20,
62
+ fontWeight: "600",
63
+ marginBottom: 8,
64
+ paddingHorizontal: 24,
65
+ },
66
+ demoLabel: {
67
+ color: "#999999",
68
+ fontSize: 13,
69
+ paddingHorizontal: 24,
70
+ },
49
71
  });
50
72
 
51
73
  // ---------------------------------------------------------------------------
@@ -101,7 +123,6 @@ export type ActionButtonsStyleConfiguration = {
101
123
  };
102
124
 
103
125
  export type HeaderConfiguration = {
104
- paddingTop?: number;
105
126
  variant: HeaderVariant;
106
127
  title: TitleConfiguration;
107
128
  closeButton: CloseButtonConfiguration;
@@ -147,17 +168,12 @@ export type HeaderData = {
147
168
  title: string;
148
169
  };
149
170
 
150
- export type AudioPlayerHeaderProps = {
171
+ export type ItemProps = {
151
172
  configuration: HeaderConfiguration;
152
173
  data: HeaderData;
153
174
  focusedCloseButton?: boolean;
154
175
  focusedLeadingAction?: boolean;
155
176
  focusedTrailingAction?: boolean;
156
- onClose?: () => void;
157
- onBack?: () => void;
158
- onCancel?: () => void;
159
- onDone?: () => void;
160
- onClear?: () => void;
161
177
  };
162
178
 
163
179
  // ---------------------------------------------------------------------------
@@ -186,9 +202,9 @@ type ActionButtonsBehaviorSpec = {
186
202
  const CONTAINER_SPEC: Record<HeaderVariant, ContainerSpec> = {
187
203
  singleLine: {
188
204
  horizontalGutter: 16,
189
- paddingTop: 24,
190
- paddingRight: 20,
191
- paddingBottom: 12,
205
+ paddingTop: 0,
206
+ paddingRight: 14,
207
+ paddingBottom: 8,
192
208
  paddingLeft: 20,
193
209
  },
194
210
  headerWithActions: {
@@ -240,6 +256,9 @@ const ACTION_BUTTONS_BEHAVIOR: Record<
240
256
  },
241
257
  };
242
258
 
259
+ const DEFAULT_CLOSE_BUTTON_ASSET =
260
+ "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAl0lEQVR42u2YQQ7AIAgE/f+naQ899dDYyiLT7DyAnRijwBjGGLNEnKCy4qJCNlVYKZ2aETeUshLhTGlZbUVh5UGkB8hlM4PKZDMCy2VXgrfJfhHYLvtGpI3sjFA72SextrKz0m1bUYwsTvhX97f9C4F8g5G/HLKPQHZqyF4YOW0g5znkxCytjV6koFZVqGVg5Yc0jDFmiQNENiwNUMoCZAAAAABJRU5ErkJggg==";
261
+
243
262
  const CLOSE_BUTTON_SPEC = {
244
263
  width: 44,
245
264
  height: 44,
@@ -279,34 +298,19 @@ function shouldShowActionSlot(slot: ActionSlotSpec, sectionEnabled: boolean) {
279
298
 
280
299
  type HeaderContainerProps = {
281
300
  variant: HeaderVariant;
282
- configuration: HeaderConfiguration;
283
301
  children: React.ReactNode;
284
302
  };
285
303
 
286
- const TRANSPARENT = "transparent";
287
-
288
- function HeaderContainer({
289
- variant,
290
- configuration,
291
- children,
292
- }: HeaderContainerProps) {
304
+ function HeaderContainer({ variant, children }: HeaderContainerProps) {
293
305
  const container = CONTAINER_SPEC[variant];
294
306
 
295
- const paddingTop =
296
- configuration.paddingTop !== undefined
297
- ? configuration.paddingTop
298
- : container.paddingTop;
299
-
300
- const backgroundColor = (configuration as any).backgroundColor || TRANSPARENT;
301
-
302
307
  return (
303
308
  <View
304
309
  style={{
305
- paddingTop: paddingTop,
310
+ paddingTop: container.paddingTop,
306
311
  paddingRight: container.paddingRight,
307
312
  paddingBottom: container.paddingBottom,
308
313
  paddingLeft: container.paddingLeft,
309
- backgroundColor: backgroundColor,
310
314
  }}
311
315
  >
312
316
  {children}
@@ -321,18 +325,17 @@ type HeaderTitleProps = {
321
325
  };
322
326
 
323
327
  function HeaderTitle({ title, configuration, centered }: HeaderTitleProps) {
324
- const { fontColor, fontSize } = configuration;
325
-
326
- const letterSpacing = isApplePlatform()
327
- ? configuration.iosLetterSpacing
328
- : configuration.androidLetterSpacing;
328
+ const letterSpacing =
329
+ Platform.OS === "ios"
330
+ ? configuration.iosLetterSpacing
331
+ : configuration.androidLetterSpacing;
329
332
 
330
333
  return (
331
334
  <Text
332
335
  style={{
333
336
  flex: centered ? undefined : 1,
334
- color: fontColor,
335
- fontSize: fontSize,
337
+ color: configuration.fontColor,
338
+ fontSize: configuration.fontSize,
336
339
  lineHeight: configuration.lineHeight,
337
340
  letterSpacing,
338
341
  fontFamily: Platform.select({
@@ -353,80 +356,21 @@ function HeaderTitle({ title, configuration, centered }: HeaderTitleProps) {
353
356
  type HeaderCloseButtonProps = {
354
357
  configuration: CloseButtonConfiguration;
355
358
  focused?: boolean;
356
- onPress?: () => void;
357
359
  };
358
360
 
359
361
  function HeaderCloseButton({
360
362
  configuration,
361
363
  focused = false,
362
- onPress,
363
364
  }: HeaderCloseButtonProps) {
364
365
  if (!configuration.enabled) {
365
366
  return null;
366
367
  }
367
368
 
368
- const buttonSize = 32;
369
+ const asset = configuration.asset ?? DEFAULT_CLOSE_BUTTON_ASSET;
369
370
 
370
371
  return (
371
- <Pressable
372
- onPress={onPress}
373
- style={({ pressed }) => [
374
- styles.closeButton,
375
- {
376
- width: buttonSize,
377
- height: buttonSize,
378
- borderRadius: buttonSize / 2,
379
- borderWidth: 1.5,
380
- borderColor: "rgba(255, 255, 255, 0.4)",
381
- opacity: pressed || focused ? 0.7 : 1,
382
- justifyContent: "center",
383
- alignItems: "center",
384
- },
385
- ]}
386
- >
387
- <View
388
- style={{
389
- width: 14,
390
- height: 14,
391
- justifyContent: "center",
392
- alignItems: "center",
393
- }}
394
- >
395
- <View
396
- style={{
397
- position: "absolute",
398
- width: 14,
399
- height: 1.5,
400
- backgroundColor: "#FFFFFF",
401
- transform: [{ rotate: "45deg" }],
402
- borderRadius: 1,
403
- }}
404
- />
405
- <View
406
- style={{
407
- position: "absolute",
408
- width: 14,
409
- height: 1.5,
410
- backgroundColor: "#FFFFFF",
411
- transform: [{ rotate: "-45deg" }],
412
- borderRadius: 1,
413
- }}
414
- />
415
- </View>
416
- </Pressable>
417
- );
418
- }
419
-
420
- type HeaderBackButtonProps = {
421
- focused?: boolean;
422
- onPress?: () => void;
423
- };
424
-
425
- function HeaderBackButton({ focused = false, onPress }: HeaderBackButtonProps) {
426
- return (
427
- <Pressable
428
- onPress={onPress}
429
- style={({ pressed }) => [
372
+ <View
373
+ style={[
430
374
  styles.closeButton,
431
375
  {
432
376
  width: CLOSE_BUTTON_SPEC.width,
@@ -438,14 +382,19 @@ function HeaderBackButton({ focused = false, onPress }: HeaderBackButtonProps) {
438
382
  borderRadius: CLOSE_BUTTON_SPEC.width / 2,
439
383
  borderWidth: 1,
440
384
  borderColor: "#FFFFFF",
441
- opacity: pressed || focused ? 0.7 : 1,
385
+ opacity: focused ? 0.7 : 1,
442
386
  },
443
387
  ]}
444
388
  >
445
- <Text style={{ color: "#FFFFFF", fontSize: 20, fontWeight: "bold" }}>
446
- ‹
447
- </Text>
448
- </Pressable>
389
+ <Image
390
+ source={{ uri: asset }}
391
+ style={{
392
+ width: CLOSE_BUTTON_SPEC.width * 0.55,
393
+ height: CLOSE_BUTTON_SPEC.height * 0.55,
394
+ }}
395
+ resizeMode="contain"
396
+ />
397
+ </View>
449
398
  );
450
399
  }
451
400
 
@@ -453,29 +402,25 @@ type HeaderActionButtonProps = {
453
402
  actionType: HeaderActionType;
454
403
  configuration: ActionButtonsStyleConfiguration;
455
404
  focused?: boolean;
456
- onPress?: () => void;
457
405
  };
458
406
 
459
407
  function HeaderActionButton({
460
408
  actionType,
461
409
  configuration,
462
410
  focused = false,
463
- onPress,
464
411
  }: HeaderActionButtonProps) {
465
412
  return (
466
- <Pressable
467
- onPress={onPress}
468
- style={({ pressed }) => ({
469
- backgroundColor:
470
- pressed || focused
471
- ? configuration.focusedBackgroundColor
472
- : configuration.defaultBackgroundColor,
413
+ <View
414
+ style={{
415
+ backgroundColor: focused
416
+ ? configuration.focusedBackgroundColor
417
+ : configuration.defaultBackgroundColor,
473
418
  borderRadius: ACTION_BUTTON_LAYOUT_SPEC.cornerRadius,
474
419
  paddingTop: ACTION_BUTTON_LAYOUT_SPEC.paddingTop,
475
420
  paddingRight: ACTION_BUTTON_LAYOUT_SPEC.paddingRight,
476
421
  paddingBottom: ACTION_BUTTON_LAYOUT_SPEC.paddingBottom,
477
422
  paddingLeft: ACTION_BUTTON_LAYOUT_SPEC.paddingLeft,
478
- })}
423
+ }}
479
424
  >
480
425
  <Text
481
426
  style={{
@@ -499,7 +444,7 @@ function HeaderActionButton({
499
444
  >
500
445
  {ACTION_LABELS[actionType]}
501
446
  </Text>
502
- </Pressable>
447
+ </View>
503
448
  );
504
449
  }
505
450
 
@@ -591,32 +536,17 @@ function CenterAlignedHeaderLayout({
591
536
  }
592
537
 
593
538
  // ---------------------------------------------------------------------------
594
- // AudioPlayerHeader
539
+ // Item
595
540
  // ---------------------------------------------------------------------------
596
541
 
597
- import { useModalBlocksStyle } from "../../ModalBlocksStyleContext";
598
- import { mergeHeaderConfiguration } from "../utils/mergeStyles";
599
-
600
- export function AudioPlayerHeader({
542
+ export function Item({
601
543
  configuration,
602
544
  data,
603
545
  focusedCloseButton = false,
604
546
  focusedLeadingAction = false,
605
547
  focusedTrailingAction = false,
606
- onClose,
607
- onBack,
608
- onCancel,
609
- onDone,
610
- onClear,
611
- }: AudioPlayerHeaderProps) {
612
- const modalBlocksStyle = useModalBlocksStyle();
613
- const headerBlock = modalBlocksStyle?.header;
614
-
615
- const effectiveConfig = React.useMemo(() => {
616
- return mergeHeaderConfiguration(configuration, headerBlock);
617
- }, [configuration, headerBlock]);
618
-
619
- const { variant, title, closeButton, actionButtons } = effectiveConfig;
548
+ }: ItemProps) {
549
+ const { variant, title, closeButton, actionButtons } = configuration;
620
550
  const { title: titleText } = data;
621
551
 
622
552
  const container = CONTAINER_SPEC[variant];
@@ -638,10 +568,7 @@ export function AudioPlayerHeader({
638
568
  actionType={behavior.leading.actionType}
639
569
  configuration={actionButtons}
640
570
  focused={focusedLeadingAction}
641
- onPress={onCancel}
642
571
  />
643
- ) : onBack ? (
644
- <HeaderBackButton focused={focusedCloseButton} onPress={onBack} />
645
572
  ) : null;
646
573
 
647
574
  const trailingContent = showTrailingAction ? (
@@ -649,19 +576,17 @@ export function AudioPlayerHeader({
649
576
  actionType={behavior.trailing.actionType}
650
577
  configuration={actionButtons}
651
578
  focused={focusedTrailingAction}
652
- onPress={behavior.trailing.actionType === "done" ? onDone : onClear}
653
579
  />
654
580
  ) : closeButton.enabled && !isCenterAligned ? (
655
581
  <HeaderCloseButton
656
582
  configuration={closeButton}
657
583
  focused={focusedCloseButton}
658
- onPress={onClose}
659
584
  />
660
585
  ) : null;
661
586
 
662
587
  if (isCenterAligned) {
663
588
  return (
664
- <HeaderContainer variant={variant} configuration={configuration}>
589
+ <HeaderContainer variant={variant}>
665
590
  <CenterAlignedHeaderLayout
666
591
  horizontalGutter={container.horizontalGutter}
667
592
  title={title}
@@ -674,7 +599,7 @@ export function AudioPlayerHeader({
674
599
  }
675
600
 
676
601
  return (
677
- <HeaderContainer variant={variant} configuration={configuration}>
602
+ <HeaderContainer variant={variant}>
678
603
  <View style={styles.row}>
679
604
  {leadingContent ? (
680
605
  <>
@@ -722,7 +647,6 @@ export const VARIANT_HEADER_WITH_ACTIONS: HeaderConfiguration = {
722
647
  },
723
648
  closeButton: { enabled: false },
724
649
  actionButtons: DEFAULT_ACTION_BUTTONS_STYLE_CONFIGURATION,
725
- paddingTop: 16,
726
650
  };
727
651
 
728
652
  /** Variant 2 — single side action (layout rule demo) */
@@ -741,7 +665,6 @@ export const VARIANT_HEADER_WITH_CANCEL_ONLY: HeaderConfiguration = {
741
665
  },
742
666
  closeButton: { enabled: false },
743
667
  actionButtons: DEFAULT_ACTION_BUTTONS_STYLE_CONFIGURATION,
744
- paddingTop: 16,
745
668
  };
746
669
 
747
670
  /** Variant 3 — Section Header */
@@ -761,3 +684,45 @@ export const VARIANT_SECTION_HEADER: HeaderConfiguration = {
761
684
  closeButton: { enabled: false },
762
685
  actionButtons: DEFAULT_ACTION_BUTTONS_STYLE_CONFIGURATION,
763
686
  };
687
+
688
+ export default function App() {
689
+ return (
690
+ <View style={styles.demoScreen}>
691
+ <Text style={styles.demoHeading}>Modal Header Building Block</Text>
692
+
693
+ <View style={styles.demoBlock}>
694
+ <Text style={styles.demoLabel}>Single Line Header</Text>
695
+ <Item
696
+ configuration={VARIANT_SINGLE_LINE_HEADER}
697
+ data={{ title: "Playback Speed" }}
698
+ />
699
+ </View>
700
+
701
+ <View style={styles.demoBlock}>
702
+ <Text style={styles.demoLabel}>Header With Actions</Text>
703
+ <Item
704
+ configuration={VARIANT_HEADER_WITH_ACTIONS}
705
+ data={{ title: "Playback Speed" }}
706
+ />
707
+ </View>
708
+
709
+ <View style={styles.demoBlock}>
710
+ <Text style={styles.demoLabel}>
711
+ Header With Actions — single side action
712
+ </Text>
713
+ <Item
714
+ configuration={VARIANT_HEADER_WITH_CANCEL_ONLY}
715
+ data={{ title: "Playback Speed" }}
716
+ />
717
+ </View>
718
+
719
+ <View style={styles.demoBlock}>
720
+ <Text style={styles.demoLabel}>Section Header</Text>
721
+ <Item
722
+ configuration={VARIANT_SECTION_HEADER}
723
+ data={{ title: "Next in Queue" }}
724
+ />
725
+ </View>
726
+ </View>
727
+ );
728
+ }