@applicaster/zapp-react-native-ui-components 16.0.0-rc.80 → 16.0.0-rc.81
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/ModalComponent/AudioPlayer/Components/Button.tsx +15 -3
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +91 -5
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +230 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +151 -18
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +1 -1
- package/Components/ModalComponent/utils.ts +6 -1
- package/Components/OfflineHandler/hooks.ts +0 -12
- package/package.json +5 -5
|
@@ -81,6 +81,8 @@ export type LeadingIconConfiguration = {
|
|
|
81
81
|
enabled: boolean;
|
|
82
82
|
/** Decides which icon will be displayed when enabled */
|
|
83
83
|
actionType?: ButtonActionType;
|
|
84
|
+
/** Optional Studio / modal-blocks asset URI (overrides actionType mapping) */
|
|
85
|
+
asset?: string;
|
|
84
86
|
};
|
|
85
87
|
|
|
86
88
|
export type IconsConfiguration = {
|
|
@@ -170,7 +172,9 @@ function getTextTransformStyle(
|
|
|
170
172
|
}
|
|
171
173
|
|
|
172
174
|
function shouldShowLeadingIcon(leadingIcon: LeadingIconConfiguration) {
|
|
173
|
-
return
|
|
175
|
+
return (
|
|
176
|
+
leadingIcon.enabled && (!!leadingIcon.actionType || !!leadingIcon.asset)
|
|
177
|
+
);
|
|
174
178
|
}
|
|
175
179
|
|
|
176
180
|
// ---------------------------------------------------------------------------
|
|
@@ -268,7 +272,7 @@ function ButtonTitle({
|
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
type ButtonLeadingIconProps = {
|
|
271
|
-
actionType
|
|
275
|
+
actionType?: ButtonActionType;
|
|
272
276
|
configuration: IconsConfiguration;
|
|
273
277
|
};
|
|
274
278
|
|
|
@@ -276,9 +280,17 @@ function ButtonLeadingIcon({
|
|
|
276
280
|
actionType,
|
|
277
281
|
configuration,
|
|
278
282
|
}: ButtonLeadingIconProps) {
|
|
283
|
+
const asset =
|
|
284
|
+
configuration.leadingIcon.asset ||
|
|
285
|
+
(actionType ? ACTION_ICON_ASSETS[actionType] : undefined);
|
|
286
|
+
|
|
287
|
+
if (!asset) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
|
|
279
291
|
return (
|
|
280
292
|
<Image
|
|
281
|
-
source={{ uri:
|
|
293
|
+
source={{ uri: asset }}
|
|
282
294
|
style={{
|
|
283
295
|
width: configuration.width,
|
|
284
296
|
height: configuration.height,
|
|
@@ -56,6 +56,10 @@ export type BackgroundConfiguration = {
|
|
|
56
56
|
defaultColor: string;
|
|
57
57
|
focusedColor: string;
|
|
58
58
|
cornerRadius: number;
|
|
59
|
+
paddingTop?: number;
|
|
60
|
+
paddingRight?: number;
|
|
61
|
+
paddingBottom?: number;
|
|
62
|
+
paddingLeft?: number;
|
|
59
63
|
};
|
|
60
64
|
|
|
61
65
|
export type ImageConfiguration = {
|
|
@@ -82,6 +86,20 @@ export type NowPlayingAssetConfiguration = {
|
|
|
82
86
|
asset?: string;
|
|
83
87
|
};
|
|
84
88
|
|
|
89
|
+
export type CheckboxAssetsConfiguration = {
|
|
90
|
+
/** Unchecked multiSelect control (item.checkbox_asset). */
|
|
91
|
+
asset?: string;
|
|
92
|
+
/** Checked multiSelect control (item.checked_checkbox_asset). */
|
|
93
|
+
checkedAsset?: string;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export type ActionButtonAssetsConfiguration = {
|
|
97
|
+
/** Leading remove control on Edit Order rows. */
|
|
98
|
+
removeAsset?: string;
|
|
99
|
+
/** Trailing drag handle on Edit Order / queue rows. */
|
|
100
|
+
dragAsset?: string;
|
|
101
|
+
};
|
|
102
|
+
|
|
85
103
|
export type ItemConfiguration = {
|
|
86
104
|
background: BackgroundConfiguration;
|
|
87
105
|
image: ImageConfiguration;
|
|
@@ -89,6 +107,8 @@ export type ItemConfiguration = {
|
|
|
89
107
|
nowPlayingLabel: LabelConfiguration;
|
|
90
108
|
textLabel1: LabelConfiguration;
|
|
91
109
|
textLabel2: LabelConfiguration;
|
|
110
|
+
checkboxAssets?: CheckboxAssetsConfiguration;
|
|
111
|
+
actionButtonAssets?: ActionButtonAssetsConfiguration;
|
|
92
112
|
};
|
|
93
113
|
|
|
94
114
|
export const DEFAULT_TEXT_LABEL_1_CONFIGURATION: LabelConfiguration = {
|
|
@@ -301,10 +321,13 @@ export function mapMenuItemToPlaylistData(
|
|
|
301
321
|
const showSelectionWidget =
|
|
302
322
|
behavior?.selectMode !== "none" && item.trailingButton !== "none";
|
|
303
323
|
|
|
324
|
+
const summary =
|
|
325
|
+
typeof item.summary === "string" ? item.summary.trim() : item.summary;
|
|
326
|
+
|
|
304
327
|
return {
|
|
305
328
|
imageUri: item.icon,
|
|
306
329
|
textLabel1: item.title,
|
|
307
|
-
textLabel2:
|
|
330
|
+
textLabel2: summary || "",
|
|
308
331
|
trailingButton: showSelectionWidget
|
|
309
332
|
? item.trailingButton || ("multiSelect" as ItemButtonAction)
|
|
310
333
|
: undefined,
|
|
@@ -340,10 +363,10 @@ function ItemContainer({
|
|
|
340
363
|
style={({ pressed }) => ({
|
|
341
364
|
backgroundColor: pressed ? background.focusedColor : bg,
|
|
342
365
|
borderRadius: background.cornerRadius,
|
|
343
|
-
paddingTop: container.paddingTop,
|
|
344
|
-
paddingRight: container.paddingRight,
|
|
345
|
-
paddingBottom: container.paddingBottom,
|
|
346
|
-
paddingLeft: container.paddingLeft,
|
|
366
|
+
paddingTop: background.paddingTop ?? container.paddingTop,
|
|
367
|
+
paddingRight: background.paddingRight ?? container.paddingRight,
|
|
368
|
+
paddingBottom: background.paddingBottom ?? container.paddingBottom,
|
|
369
|
+
paddingLeft: background.paddingLeft ?? container.paddingLeft,
|
|
347
370
|
})}
|
|
348
371
|
>
|
|
349
372
|
{children}
|
|
@@ -450,6 +473,8 @@ type ItemButtonProps = {
|
|
|
450
473
|
focused?: boolean;
|
|
451
474
|
onPress?: () => void;
|
|
452
475
|
isSelected?: boolean;
|
|
476
|
+
checkboxAssets?: CheckboxAssetsConfiguration;
|
|
477
|
+
actionButtonAssets?: ActionButtonAssetsConfiguration;
|
|
453
478
|
};
|
|
454
479
|
|
|
455
480
|
function ItemButton({
|
|
@@ -457,6 +482,8 @@ function ItemButton({
|
|
|
457
482
|
focused = false,
|
|
458
483
|
onPress,
|
|
459
484
|
isSelected = false,
|
|
485
|
+
checkboxAssets,
|
|
486
|
+
actionButtonAssets,
|
|
460
487
|
}: ItemButtonProps) {
|
|
461
488
|
const layout = BUTTON_LAYOUT_SPEC[action];
|
|
462
489
|
|
|
@@ -531,6 +558,19 @@ function ItemButton({
|
|
|
531
558
|
}
|
|
532
559
|
|
|
533
560
|
case "drag": {
|
|
561
|
+
if (actionButtonAssets?.dragAsset) {
|
|
562
|
+
return (
|
|
563
|
+
<Image
|
|
564
|
+
source={{ uri: actionButtonAssets.dragAsset }}
|
|
565
|
+
style={{
|
|
566
|
+
width: layout.assetWidth,
|
|
567
|
+
height: layout.assetHeight,
|
|
568
|
+
}}
|
|
569
|
+
resizeMode="contain"
|
|
570
|
+
/>
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
|
|
534
574
|
return (
|
|
535
575
|
<View
|
|
536
576
|
style={{
|
|
@@ -565,6 +605,19 @@ function ItemButton({
|
|
|
565
605
|
}
|
|
566
606
|
|
|
567
607
|
case "remove": {
|
|
608
|
+
if (actionButtonAssets?.removeAsset) {
|
|
609
|
+
return (
|
|
610
|
+
<Image
|
|
611
|
+
source={{ uri: actionButtonAssets.removeAsset }}
|
|
612
|
+
style={{
|
|
613
|
+
width: layout.assetWidth,
|
|
614
|
+
height: layout.assetHeight,
|
|
615
|
+
}}
|
|
616
|
+
resizeMode="contain"
|
|
617
|
+
/>
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
|
|
568
621
|
return (
|
|
569
622
|
<View
|
|
570
623
|
style={{
|
|
@@ -590,6 +643,23 @@ function ItemButton({
|
|
|
590
643
|
}
|
|
591
644
|
|
|
592
645
|
case "multiSelect": {
|
|
646
|
+
const studioAsset = isSelected
|
|
647
|
+
? checkboxAssets?.checkedAsset
|
|
648
|
+
: checkboxAssets?.asset;
|
|
649
|
+
|
|
650
|
+
if (studioAsset) {
|
|
651
|
+
return (
|
|
652
|
+
<Image
|
|
653
|
+
source={{ uri: studioAsset }}
|
|
654
|
+
style={{
|
|
655
|
+
width: layout.assetWidth,
|
|
656
|
+
height: layout.assetHeight,
|
|
657
|
+
}}
|
|
658
|
+
resizeMode="contain"
|
|
659
|
+
/>
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
|
|
593
663
|
if (!isSelected) {
|
|
594
664
|
return (
|
|
595
665
|
<View
|
|
@@ -666,6 +736,8 @@ type ItemButtonsProps = {
|
|
|
666
736
|
onTrailingButtonPress?: () => void;
|
|
667
737
|
isSelected?: boolean;
|
|
668
738
|
renderHandle?: (element: React.ReactElement) => React.ReactElement;
|
|
739
|
+
checkboxAssets?: CheckboxAssetsConfiguration;
|
|
740
|
+
actionButtonAssets?: ActionButtonAssetsConfiguration;
|
|
669
741
|
};
|
|
670
742
|
|
|
671
743
|
function ItemButtons({
|
|
@@ -677,6 +749,8 @@ function ItemButtons({
|
|
|
677
749
|
onTrailingButtonPress,
|
|
678
750
|
isSelected = false,
|
|
679
751
|
renderHandle,
|
|
752
|
+
checkboxAssets,
|
|
753
|
+
actionButtonAssets,
|
|
680
754
|
}: ItemButtonsProps) {
|
|
681
755
|
if (!leadingButton && !trailingButton) {
|
|
682
756
|
return null;
|
|
@@ -691,6 +765,8 @@ function ItemButtons({
|
|
|
691
765
|
focused={focusedLeadingButton}
|
|
692
766
|
onPress={onLeadingButtonPress}
|
|
693
767
|
isSelected={isSelected}
|
|
768
|
+
checkboxAssets={checkboxAssets}
|
|
769
|
+
actionButtonAssets={actionButtonAssets}
|
|
694
770
|
/>
|
|
695
771
|
<View style={{ width: BUTTONS_CONTAINER_HORIZONTAL_GUTTER }} />
|
|
696
772
|
</>
|
|
@@ -704,6 +780,8 @@ function ItemButtons({
|
|
|
704
780
|
focused={focusedTrailingButton}
|
|
705
781
|
onPress={onTrailingButtonPress}
|
|
706
782
|
isSelected={isSelected}
|
|
783
|
+
checkboxAssets={checkboxAssets}
|
|
784
|
+
actionButtonAssets={actionButtonAssets}
|
|
707
785
|
/>
|
|
708
786
|
)
|
|
709
787
|
) : (
|
|
@@ -712,6 +790,8 @@ function ItemButtons({
|
|
|
712
790
|
focused={focusedTrailingButton}
|
|
713
791
|
onPress={onTrailingButtonPress}
|
|
714
792
|
isSelected={isSelected}
|
|
793
|
+
checkboxAssets={checkboxAssets}
|
|
794
|
+
actionButtonAssets={actionButtonAssets}
|
|
715
795
|
/>
|
|
716
796
|
)
|
|
717
797
|
) : (
|
|
@@ -720,6 +800,8 @@ function ItemButtons({
|
|
|
720
800
|
focused={focusedTrailingButton}
|
|
721
801
|
onPress={onTrailingButtonPress}
|
|
722
802
|
isSelected={isSelected}
|
|
803
|
+
checkboxAssets={checkboxAssets}
|
|
804
|
+
actionButtonAssets={actionButtonAssets}
|
|
723
805
|
/>
|
|
724
806
|
)
|
|
725
807
|
) : null}
|
|
@@ -761,6 +843,8 @@ export function AudioPlayerTrackItem({
|
|
|
761
843
|
textLabel2,
|
|
762
844
|
nowPlayingLabel,
|
|
763
845
|
nowPlayingAsset,
|
|
846
|
+
checkboxAssets,
|
|
847
|
+
actionButtonAssets,
|
|
764
848
|
} = effectiveConfig;
|
|
765
849
|
|
|
766
850
|
const container = resolveContainerSpec(image);
|
|
@@ -803,6 +887,8 @@ export function AudioPlayerTrackItem({
|
|
|
803
887
|
onTrailingButtonPress={onTrailingButtonPress}
|
|
804
888
|
isSelected={data.isSelected}
|
|
805
889
|
renderHandle={renderHandle}
|
|
890
|
+
checkboxAssets={checkboxAssets}
|
|
891
|
+
actionButtonAssets={actionButtonAssets}
|
|
806
892
|
/>
|
|
807
893
|
</View>
|
|
808
894
|
</ItemContainer>
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergeItemConfiguration,
|
|
3
|
+
mergeButtonConfiguration,
|
|
4
|
+
} from "../mergeStyles";
|
|
5
|
+
|
|
6
|
+
const base = {
|
|
7
|
+
background: {
|
|
8
|
+
defaultColor: "transparent",
|
|
9
|
+
focusedColor: "rgba(62, 62, 62, 1)",
|
|
10
|
+
cornerRadius: 12,
|
|
11
|
+
},
|
|
12
|
+
image: {
|
|
13
|
+
width: 48,
|
|
14
|
+
height: 48,
|
|
15
|
+
borderWidth: 1,
|
|
16
|
+
borderColor: "rgba(255, 255, 255, 0.1)",
|
|
17
|
+
cornerRadius: 6,
|
|
18
|
+
},
|
|
19
|
+
nowPlayingAsset: {},
|
|
20
|
+
nowPlayingLabel: { fontColor: "#fff", fontSize: 12 },
|
|
21
|
+
textLabel1: { fontColor: "#fff", fontSize: 15 },
|
|
22
|
+
textLabel2: { fontColor: "#999", fontSize: 13 },
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
describe("mergeItemConfiguration background", () => {
|
|
26
|
+
it("applies Studio focus background to focusedColor", () => {
|
|
27
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
28
|
+
background: {
|
|
29
|
+
default: { backgroundColor: "transparent" },
|
|
30
|
+
focused: { backgroundColor: "#FF3B30" },
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(merged.background.defaultColor).toBe("transparent");
|
|
35
|
+
expect(merged.background.focusedColor).toBe("#FF3B30");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("accepts focus alias bucket from parser output", () => {
|
|
39
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
40
|
+
background: {
|
|
41
|
+
default: { backgroundColor: "transparent" },
|
|
42
|
+
focus: { backgroundColor: "#00FF66" },
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
expect(merged.background.focusedColor).toBe("#00FF66");
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("merges text label lineHeight from Studio keys", () => {
|
|
50
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
51
|
+
textLabel1: {
|
|
52
|
+
default: { fontSize: 28, lineHeight: 40 },
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
expect(merged.textLabel1.fontSize).toBe(28);
|
|
57
|
+
expect(merged.textLabel1.lineHeight).toBe(40);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("merges background padding from Studio keys", () => {
|
|
61
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
62
|
+
background: {
|
|
63
|
+
default: {
|
|
64
|
+
backgroundColor: "#2E7D32",
|
|
65
|
+
paddingTop: 32,
|
|
66
|
+
paddingBottom: 32,
|
|
67
|
+
paddingLeft: 40,
|
|
68
|
+
paddingRight: 40,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
expect(merged.background.paddingTop).toBe(32);
|
|
74
|
+
expect(merged.background.paddingBottom).toBe(32);
|
|
75
|
+
expect(merged.background.paddingLeft).toBe(40);
|
|
76
|
+
expect(merged.background.paddingRight).toBe(40);
|
|
77
|
+
// Default-only override must not steal the base focused highlight color.
|
|
78
|
+
expect(merged.background.focusedColor).toBe("rgba(62, 62, 62, 1)");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("preserves base focusedColor when only default background is set", () => {
|
|
82
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
83
|
+
background: {
|
|
84
|
+
default: { backgroundColor: "#2E7D32" },
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(merged.background.defaultColor).toBe("#2E7D32");
|
|
89
|
+
expect(merged.background.focusedColor).toBe("rgba(62, 62, 62, 1)");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it("applies Studio checkbox assets onto checkboxAssets", () => {
|
|
93
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
94
|
+
checkbox: {
|
|
95
|
+
default: {
|
|
96
|
+
asset: "https://placehold.co/24x24/FF3B30/FFFFFF/png?text=CB",
|
|
97
|
+
checkedAsset: "https://placehold.co/24x24/FFD60A/000000/png?text=CK",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
expect(merged.checkboxAssets?.asset).toBe(
|
|
103
|
+
"https://placehold.co/24x24/FF3B30/FFFFFF/png?text=CB"
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
expect(merged.checkboxAssets?.checkedAsset).toBe(
|
|
107
|
+
"https://placehold.co/24x24/FFD60A/000000/png?text=CK"
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("applies Studio reorder/remove assets onto actionButtonAssets", () => {
|
|
112
|
+
const merged = mergeItemConfiguration(base as any, {
|
|
113
|
+
actionButtons: {
|
|
114
|
+
default: {
|
|
115
|
+
removeAsset: "https://placehold.co/24x24/00FF00/000000/png?text=RM",
|
|
116
|
+
dragAsset: "https://placehold.co/24x24/FF3B30/FFFFFF/png?text=RH",
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
expect(merged.actionButtonAssets?.removeAsset).toBe(
|
|
122
|
+
"https://placehold.co/24x24/00FF00/000000/png?text=RM"
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
expect(merged.actionButtonAssets?.dragAsset).toBe(
|
|
126
|
+
"https://placehold.co/24x24/FF3B30/FFFFFF/png?text=RH"
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
describe("mergeButtonConfiguration background", () => {
|
|
132
|
+
const buttonBase = {
|
|
133
|
+
background: {
|
|
134
|
+
defaultColor: "#FFFFFF",
|
|
135
|
+
focusedColor: "#E0E0E0",
|
|
136
|
+
inactiveColor: "#CCCCCC",
|
|
137
|
+
cornerRadius: 12,
|
|
138
|
+
paddingTop: 12,
|
|
139
|
+
paddingRight: 12,
|
|
140
|
+
paddingBottom: 12,
|
|
141
|
+
paddingLeft: 12,
|
|
142
|
+
horizontalGutter: 8,
|
|
143
|
+
},
|
|
144
|
+
title: {
|
|
145
|
+
fontColor: "#000000",
|
|
146
|
+
focusedFontColor: "#000000",
|
|
147
|
+
inactiveFontColor: "#666666",
|
|
148
|
+
iosFontFamily: "SFProText-Semibold",
|
|
149
|
+
androidFontFamily: "Roboto-Medium",
|
|
150
|
+
fontSize: 15,
|
|
151
|
+
lineHeight: 24,
|
|
152
|
+
iosLetterSpacing: 0,
|
|
153
|
+
androidLetterSpacing: 0,
|
|
154
|
+
textTransform: "default" as const,
|
|
155
|
+
},
|
|
156
|
+
icons: {
|
|
157
|
+
width: 24,
|
|
158
|
+
height: 24,
|
|
159
|
+
leadingIcon: { enabled: true },
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
it("applies Studio button focus background to focusedColor", () => {
|
|
164
|
+
const merged = mergeButtonConfiguration(buttonBase as any, {
|
|
165
|
+
background: {
|
|
166
|
+
default: { backgroundColor: "#FFFFFF" },
|
|
167
|
+
focused: { backgroundColor: "#00FF00" },
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(merged.background.defaultColor).toBe("#FFFFFF");
|
|
172
|
+
expect(merged.background.focusedColor).toBe("#00FF00");
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("applies Studio button title lineHeight", () => {
|
|
176
|
+
const merged = mergeButtonConfiguration(buttonBase as any, {
|
|
177
|
+
title: {
|
|
178
|
+
default: { fontColor: "#000000", fontSize: 15, lineHeight: 40 },
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
expect(merged.title.lineHeight).toBe(40);
|
|
183
|
+
expect(merged.title.fontSize).toBe(15);
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it("applies Studio button background padding", () => {
|
|
187
|
+
const merged = mergeButtonConfiguration(buttonBase as any, {
|
|
188
|
+
background: {
|
|
189
|
+
default: {
|
|
190
|
+
backgroundColor: "#FFFFFF",
|
|
191
|
+
paddingTop: 32,
|
|
192
|
+
paddingRight: 20,
|
|
193
|
+
paddingBottom: 8,
|
|
194
|
+
paddingLeft: 4,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
expect(merged.background.paddingTop).toBe(32);
|
|
200
|
+
expect(merged.background.paddingRight).toBe(20);
|
|
201
|
+
expect(merged.background.paddingBottom).toBe(8);
|
|
202
|
+
expect(merged.background.paddingLeft).toBe(4);
|
|
203
|
+
expect(merged.background.focusedColor).toBe("#E0E0E0");
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("preserves base button focusedColor when only default background is set", () => {
|
|
207
|
+
const merged = mergeButtonConfiguration(buttonBase as any, {
|
|
208
|
+
background: {
|
|
209
|
+
default: { backgroundColor: "#ABCDEF" },
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
expect(merged.background.defaultColor).toBe("#ABCDEF");
|
|
214
|
+
expect(merged.background.focusedColor).toBe("#E0E0E0");
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("applies Studio create-new leading icon asset", () => {
|
|
218
|
+
const merged = mergeButtonConfiguration(buttonBase as any, {
|
|
219
|
+
leadingIcon: {
|
|
220
|
+
default: {
|
|
221
|
+
asset: "https://placehold.co/24x24/FF00FF/FFFFFF/png?text=CN",
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
expect(merged.icons.leadingIcon.asset).toBe(
|
|
227
|
+
"https://placehold.co/24x24/FF00FF/FFFFFF/png?text=CN"
|
|
228
|
+
);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
ImageConfiguration as ItemImageConfiguration,
|
|
4
4
|
LabelConfiguration as ItemLabelConfiguration,
|
|
5
5
|
NowPlayingAssetConfiguration as ItemNowPlayingAssetConfiguration,
|
|
6
|
+
CheckboxAssetsConfiguration as ItemCheckboxAssetsConfiguration,
|
|
7
|
+
ActionButtonAssetsConfiguration as ItemActionButtonAssetsConfiguration,
|
|
6
8
|
ItemConfiguration,
|
|
7
9
|
} from "../Components/Item";
|
|
8
10
|
import {
|
|
@@ -21,20 +23,39 @@ import {
|
|
|
21
23
|
|
|
22
24
|
function mergeItemBackground(
|
|
23
25
|
base: ItemBackgroundConfiguration,
|
|
24
|
-
|
|
26
|
+
defaultOverride?: Record<string, any>,
|
|
27
|
+
focusedOverride?: Record<string, any>
|
|
25
28
|
): ItemBackgroundConfiguration {
|
|
26
|
-
if (!
|
|
29
|
+
if (!defaultOverride && !focusedOverride) return base;
|
|
30
|
+
|
|
31
|
+
// Only take focused color from the focused/pressed bucket (or legacy
|
|
32
|
+
// mis-parsed focus* aliases). Never fall back to default background —
|
|
33
|
+
// that would overwrite base.focusedColor whenever Studio only sets default.
|
|
34
|
+
const focusedColor =
|
|
35
|
+
focusedOverride?.backgroundColor ??
|
|
36
|
+
defaultOverride?.focusColor ??
|
|
37
|
+
defaultOverride?.focusBackgroundColor;
|
|
27
38
|
|
|
28
39
|
return {
|
|
29
40
|
...base,
|
|
30
|
-
...(
|
|
31
|
-
? { defaultColor:
|
|
41
|
+
...(defaultOverride?.backgroundColor
|
|
42
|
+
? { defaultColor: defaultOverride.backgroundColor }
|
|
32
43
|
: {}),
|
|
33
|
-
...(
|
|
34
|
-
|
|
44
|
+
...(focusedColor != null && focusedColor !== "" ? { focusedColor } : {}),
|
|
45
|
+
...(defaultOverride?.borderRadius !== undefined
|
|
46
|
+
? { cornerRadius: defaultOverride.borderRadius }
|
|
35
47
|
: {}),
|
|
36
|
-
...(
|
|
37
|
-
? {
|
|
48
|
+
...(defaultOverride?.paddingTop !== undefined
|
|
49
|
+
? { paddingTop: defaultOverride.paddingTop }
|
|
50
|
+
: {}),
|
|
51
|
+
...(defaultOverride?.paddingRight !== undefined
|
|
52
|
+
? { paddingRight: defaultOverride.paddingRight }
|
|
53
|
+
: {}),
|
|
54
|
+
...(defaultOverride?.paddingBottom !== undefined
|
|
55
|
+
? { paddingBottom: defaultOverride.paddingBottom }
|
|
56
|
+
: {}),
|
|
57
|
+
...(defaultOverride?.paddingLeft !== undefined
|
|
58
|
+
? { paddingLeft: defaultOverride.paddingLeft }
|
|
38
59
|
: {}),
|
|
39
60
|
};
|
|
40
61
|
}
|
|
@@ -69,6 +90,9 @@ function mergeItemLabel(
|
|
|
69
90
|
...base,
|
|
70
91
|
...(override.fontColor ? { fontColor: override.fontColor } : {}),
|
|
71
92
|
...(override.fontSize !== undefined ? { fontSize: override.fontSize } : {}),
|
|
93
|
+
...(override.lineHeight !== undefined
|
|
94
|
+
? { lineHeight: override.lineHeight }
|
|
95
|
+
: {}),
|
|
72
96
|
};
|
|
73
97
|
}
|
|
74
98
|
|
|
@@ -84,13 +108,45 @@ function mergeItemNowPlayingAsset(
|
|
|
84
108
|
};
|
|
85
109
|
}
|
|
86
110
|
|
|
111
|
+
function mergeItemCheckboxAssets(
|
|
112
|
+
base: ItemCheckboxAssetsConfiguration,
|
|
113
|
+
override?: Record<string, any>
|
|
114
|
+
): ItemCheckboxAssetsConfiguration {
|
|
115
|
+
if (!override) return base;
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
...base,
|
|
119
|
+
...(override.asset ? { asset: override.asset } : {}),
|
|
120
|
+
...(override.checkedAsset ? { checkedAsset: override.checkedAsset } : {}),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function mergeItemActionButtonAssets(
|
|
125
|
+
base: ItemActionButtonAssetsConfiguration,
|
|
126
|
+
override?: Record<string, any>
|
|
127
|
+
): ItemActionButtonAssetsConfiguration {
|
|
128
|
+
if (!override) return base;
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
...base,
|
|
132
|
+
...(override.removeAsset ? { removeAsset: override.removeAsset } : {}),
|
|
133
|
+
...(override.dragAsset ? { dragAsset: override.dragAsset } : {}),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
87
137
|
export function mergeItemConfiguration(
|
|
88
138
|
base: ItemConfiguration,
|
|
89
139
|
itemBlock?: Record<string, any>
|
|
90
140
|
): ItemConfiguration {
|
|
91
141
|
if (!itemBlock) return base;
|
|
92
142
|
|
|
93
|
-
const
|
|
143
|
+
const bgDefault = itemBlock.background?.default || itemBlock.background;
|
|
144
|
+
|
|
145
|
+
const bgFocused =
|
|
146
|
+
itemBlock.background?.focused ||
|
|
147
|
+
itemBlock.background?.focus ||
|
|
148
|
+
itemBlock.background?.pressed;
|
|
149
|
+
|
|
94
150
|
const img = itemBlock.image?.default || itemBlock.image;
|
|
95
151
|
const label1 = itemBlock.textLabel1?.default || itemBlock.textLabel1;
|
|
96
152
|
const label2 = itemBlock.textLabel2?.default || itemBlock.textLabel2;
|
|
@@ -101,14 +157,27 @@ export function mergeItemConfiguration(
|
|
|
101
157
|
const npAsset =
|
|
102
158
|
itemBlock.nowPlayingAsset?.default || itemBlock.nowPlayingAsset;
|
|
103
159
|
|
|
160
|
+
const checkbox = itemBlock.checkbox?.default || itemBlock.checkbox;
|
|
161
|
+
|
|
162
|
+
const actionButtons =
|
|
163
|
+
itemBlock.actionButtons?.default || itemBlock.actionButtons;
|
|
164
|
+
|
|
104
165
|
return {
|
|
105
166
|
...base,
|
|
106
|
-
background: mergeItemBackground(base.background,
|
|
167
|
+
background: mergeItemBackground(base.background, bgDefault, bgFocused),
|
|
107
168
|
image: mergeItemImage(base.image, img),
|
|
108
169
|
textLabel1: mergeItemLabel(base.textLabel1, label1),
|
|
109
170
|
textLabel2: mergeItemLabel(base.textLabel2, label2),
|
|
110
171
|
nowPlayingLabel: mergeItemLabel(base.nowPlayingLabel, npLabel),
|
|
111
172
|
nowPlayingAsset: mergeItemNowPlayingAsset(base.nowPlayingAsset, npAsset),
|
|
173
|
+
checkboxAssets: mergeItemCheckboxAssets(
|
|
174
|
+
base.checkboxAssets || {},
|
|
175
|
+
checkbox
|
|
176
|
+
),
|
|
177
|
+
actionButtonAssets: mergeItemActionButtonAssets(
|
|
178
|
+
base.actionButtonAssets || {},
|
|
179
|
+
actionButtons
|
|
180
|
+
),
|
|
112
181
|
};
|
|
113
182
|
}
|
|
114
183
|
|
|
@@ -150,17 +219,37 @@ export function mergeHeaderConfiguration(
|
|
|
150
219
|
|
|
151
220
|
function mergeButtonBackground(
|
|
152
221
|
base: ButtonBackgroundConfiguration,
|
|
153
|
-
|
|
222
|
+
defaultOverride?: Record<string, any>,
|
|
223
|
+
focusedOverride?: Record<string, any>
|
|
154
224
|
): ButtonBackgroundConfiguration {
|
|
155
|
-
if (!
|
|
225
|
+
if (!defaultOverride && !focusedOverride) return base;
|
|
226
|
+
|
|
227
|
+
// Same as mergeItemBackground: do not use default background as focusedColor.
|
|
228
|
+
const focusedColor =
|
|
229
|
+
focusedOverride?.backgroundColor ??
|
|
230
|
+
defaultOverride?.focusColor ??
|
|
231
|
+
defaultOverride?.focusBackgroundColor;
|
|
156
232
|
|
|
157
233
|
return {
|
|
158
234
|
...base,
|
|
159
|
-
...(
|
|
160
|
-
? { defaultColor:
|
|
235
|
+
...(defaultOverride?.backgroundColor
|
|
236
|
+
? { defaultColor: defaultOverride.backgroundColor }
|
|
161
237
|
: {}),
|
|
162
|
-
...(
|
|
163
|
-
|
|
238
|
+
...(focusedColor != null && focusedColor !== "" ? { focusedColor } : {}),
|
|
239
|
+
...(defaultOverride?.borderRadius !== undefined
|
|
240
|
+
? { cornerRadius: defaultOverride.borderRadius }
|
|
241
|
+
: {}),
|
|
242
|
+
...(defaultOverride?.paddingTop !== undefined
|
|
243
|
+
? { paddingTop: defaultOverride.paddingTop }
|
|
244
|
+
: {}),
|
|
245
|
+
...(defaultOverride?.paddingRight !== undefined
|
|
246
|
+
? { paddingRight: defaultOverride.paddingRight }
|
|
247
|
+
: {}),
|
|
248
|
+
...(defaultOverride?.paddingBottom !== undefined
|
|
249
|
+
? { paddingBottom: defaultOverride.paddingBottom }
|
|
250
|
+
: {}),
|
|
251
|
+
...(defaultOverride?.paddingLeft !== undefined
|
|
252
|
+
? { paddingLeft: defaultOverride.paddingLeft }
|
|
164
253
|
: {}),
|
|
165
254
|
};
|
|
166
255
|
}
|
|
@@ -175,6 +264,38 @@ function mergeButtonTitle(
|
|
|
175
264
|
...base,
|
|
176
265
|
...(override.fontColor ? { fontColor: override.fontColor } : {}),
|
|
177
266
|
...(override.fontSize !== undefined ? { fontSize: override.fontSize } : {}),
|
|
267
|
+
...(override.lineHeight !== undefined
|
|
268
|
+
? { lineHeight: override.lineHeight }
|
|
269
|
+
: {}),
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function mergeButtonIcons(
|
|
274
|
+
base: ButtonConfiguration["icons"],
|
|
275
|
+
iconsOverride?: Record<string, any>,
|
|
276
|
+
leadingOverride?: Record<string, any>
|
|
277
|
+
): ButtonConfiguration["icons"] {
|
|
278
|
+
if (!iconsOverride && !leadingOverride) return base;
|
|
279
|
+
|
|
280
|
+
const iconsDefault = iconsOverride?.default || iconsOverride;
|
|
281
|
+
const leadingDefault = leadingOverride?.default || leadingOverride;
|
|
282
|
+
|
|
283
|
+
return {
|
|
284
|
+
...base,
|
|
285
|
+
...(iconsDefault?.width !== undefined ? { width: iconsDefault.width } : {}),
|
|
286
|
+
...(iconsDefault?.height !== undefined
|
|
287
|
+
? { height: iconsDefault.height }
|
|
288
|
+
: {}),
|
|
289
|
+
leadingIcon: {
|
|
290
|
+
...base.leadingIcon,
|
|
291
|
+
...(leadingDefault?.enabled !== undefined
|
|
292
|
+
? { enabled: leadingDefault.enabled }
|
|
293
|
+
: {}),
|
|
294
|
+
...(leadingDefault?.actionType
|
|
295
|
+
? { actionType: leadingDefault.actionType }
|
|
296
|
+
: {}),
|
|
297
|
+
...(leadingDefault?.asset ? { asset: leadingDefault.asset } : {}),
|
|
298
|
+
},
|
|
178
299
|
};
|
|
179
300
|
}
|
|
180
301
|
|
|
@@ -185,15 +306,27 @@ export function mergeButtonConfiguration(
|
|
|
185
306
|
): ButtonConfiguration {
|
|
186
307
|
if (!buttonBlock && !actionBlock) return base;
|
|
187
308
|
|
|
188
|
-
const
|
|
309
|
+
const bgDefault =
|
|
189
310
|
buttonBlock?.background?.default || actionBlock?.background?.default;
|
|
190
311
|
|
|
312
|
+
const bgFocused =
|
|
313
|
+
buttonBlock?.background?.focused ||
|
|
314
|
+
buttonBlock?.background?.focus ||
|
|
315
|
+
actionBlock?.background?.focused ||
|
|
316
|
+
actionBlock?.background?.focus ||
|
|
317
|
+
buttonBlock?.background?.pressed ||
|
|
318
|
+
actionBlock?.background?.pressed;
|
|
319
|
+
|
|
191
320
|
const titleOverride =
|
|
192
321
|
buttonBlock?.title?.default || actionBlock?.title?.default;
|
|
193
322
|
|
|
323
|
+
const iconsOverride = buttonBlock?.icons || actionBlock?.icons;
|
|
324
|
+
const leadingOverride = buttonBlock?.leadingIcon || actionBlock?.leadingIcon;
|
|
325
|
+
|
|
194
326
|
return {
|
|
195
327
|
...base,
|
|
196
|
-
background: mergeButtonBackground(base.background,
|
|
328
|
+
background: mergeButtonBackground(base.background, bgDefault, bgFocused),
|
|
197
329
|
title: mergeButtonTitle(base.title, titleOverride),
|
|
330
|
+
icons: mergeButtonIcons(base.icons, iconsOverride, leadingOverride),
|
|
198
331
|
};
|
|
199
332
|
}
|
|
@@ -31,10 +31,15 @@ export function defaultItemProps(
|
|
|
31
31
|
|
|
32
32
|
const bgDefault = blockItemStyle?.background?.default;
|
|
33
33
|
|
|
34
|
+
const bgFocused =
|
|
35
|
+
blockItemStyle?.background?.focused || blockItemStyle?.background?.focus;
|
|
36
|
+
|
|
34
37
|
return {
|
|
35
38
|
backgroundColor:
|
|
36
39
|
bgDefault?.backgroundColor || modal_bottom_sheet_item_background_color,
|
|
37
|
-
focusedBackgroundColor:
|
|
40
|
+
focusedBackgroundColor:
|
|
41
|
+
bgFocused?.backgroundColor ||
|
|
42
|
+
modal_bottom_sheet_item_focus_background_color,
|
|
38
43
|
selectedBackgroundColor: modal_bottom_sheet_item_selected_background_color,
|
|
39
44
|
focusedSelectedBackgroundColor:
|
|
40
45
|
modal_bottom_sheet_item_focused_selected_background_color,
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
platformSelect,
|
|
6
6
|
} from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
7
7
|
import { sessionStorage } from "@applicaster/zapp-react-native-bridge/ZappStorage/SessionStorage";
|
|
8
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
9
8
|
|
|
10
9
|
import { usePlugins } from "@applicaster/zapp-react-native-redux";
|
|
11
10
|
import { textTransform } from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
@@ -19,17 +18,6 @@ const NETWORK_STATUS_LOCALIZATIONS_KEY = "network_status_localizations";
|
|
|
19
18
|
|
|
20
19
|
const THEME_STORAGE_NAMESPACE = "quick-brick-theme";
|
|
21
20
|
|
|
22
|
-
export const useNotificationHeight = () => {
|
|
23
|
-
const insets = useSafeAreaInsets();
|
|
24
|
-
|
|
25
|
-
const navBarHeight = platformSelect({ ios: 44, android: 56 });
|
|
26
|
-
|
|
27
|
-
const statusHeight = insets.top;
|
|
28
|
-
const notificationHeight = statusHeight + navBarHeight;
|
|
29
|
-
|
|
30
|
-
return { statusHeight, notificationHeight };
|
|
31
|
-
};
|
|
32
|
-
|
|
33
21
|
export function useNetworkStatusLocalizations() {
|
|
34
22
|
const [storedLocalizations, setStoredLocalizations] = React.useState<Record<
|
|
35
23
|
string,
|
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.81",
|
|
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.81",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "16.0.0-rc.81",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "16.0.0-rc.81",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "16.0.0-rc.81",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"react-native-sortables": "1.7.1",
|