@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,5 +1,5 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import { View } from "react-native";
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
|
2
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
3
3
|
import {
|
|
4
4
|
AudioPlayerTrackItem,
|
|
5
5
|
VARIANT_NOW_PLAYING,
|
|
@@ -7,32 +7,162 @@ import {
|
|
|
7
7
|
} from "./Item";
|
|
8
8
|
import { AudioPlayerHeader, VARIANT_SECTION_HEADER } from "./Header";
|
|
9
9
|
import type { MenuItem } from "@applicaster/zapp-react-native-utils/modalState/types";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
10
|
+
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils/playerManager";
|
|
11
|
+
import { PlayerRole } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/const";
|
|
12
|
+
import type { Player } from "@applicaster/zapp-react-native-utils/appUtils/playerManager/player";
|
|
13
|
+
|
|
14
|
+
const DEFAULT_EMPTY_MESSAGE = "Queued items will be added here";
|
|
15
|
+
|
|
16
|
+
const styles = StyleSheet.create({
|
|
17
|
+
divider: {
|
|
18
|
+
height: StyleSheet.hairlineWidth,
|
|
19
|
+
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
|
20
|
+
marginHorizontal: 20,
|
|
21
|
+
marginVertical: 8,
|
|
22
|
+
},
|
|
23
|
+
emptyMessage: {
|
|
24
|
+
paddingTop: 32,
|
|
25
|
+
paddingBottom: 32,
|
|
26
|
+
paddingHorizontal: 40,
|
|
27
|
+
textAlign: "center",
|
|
28
|
+
color: "#999999",
|
|
29
|
+
fontSize: 13,
|
|
30
|
+
lineHeight: 16,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const isPrimaryOrCastingPlayer = (player?: Player | null): boolean => {
|
|
35
|
+
if (!player) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
player.playerRole === PlayerRole.Primary ||
|
|
41
|
+
player.playerRole === PlayerRole.Chromecast
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getTargetPlayer = (): Player | null => {
|
|
46
|
+
if (playerManager.isCasting()) {
|
|
47
|
+
return playerManager.getCastingReceiver() || null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const active = playerManager.getActivePlayer();
|
|
51
|
+
|
|
52
|
+
return isPrimaryOrCastingPlayer(active) ? active : null;
|
|
53
|
+
};
|
|
12
54
|
|
|
13
55
|
type NowPlayingHeaderSectionProps = {
|
|
14
56
|
onClear?: () => void;
|
|
15
57
|
nextUpTitle?: string;
|
|
16
58
|
nowPlayingTitle?: string;
|
|
59
|
+
isEmpty?: boolean;
|
|
60
|
+
emptyMessage?: string;
|
|
61
|
+
clearLabel?: string;
|
|
17
62
|
};
|
|
18
63
|
|
|
19
64
|
export function NowPlayingHeaderSection({
|
|
20
65
|
onClear,
|
|
21
66
|
nextUpTitle = "Next Up",
|
|
22
67
|
nowPlayingTitle = "Now Playing",
|
|
68
|
+
isEmpty = false,
|
|
69
|
+
emptyMessage = DEFAULT_EMPTY_MESSAGE,
|
|
70
|
+
clearLabel,
|
|
23
71
|
}: NowPlayingHeaderSectionProps) {
|
|
24
|
-
const
|
|
25
|
-
|
|
72
|
+
const [activePlayer, setActivePlayer] = useState<Player | null>(
|
|
73
|
+
getTargetPlayer
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const [currentEntry, setCurrentEntry] = useState<ZappEntry | null>(
|
|
77
|
+
() => getTargetPlayer()?.entry || null
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const [isPaused, setIsPaused] = useState<boolean>(() =>
|
|
81
|
+
Boolean(getTargetPlayer()?.isPaused())
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const handleActivePlayerUpdate = () => {
|
|
86
|
+
const player = getTargetPlayer();
|
|
87
|
+
|
|
88
|
+
if (player) {
|
|
89
|
+
setActivePlayer(player);
|
|
90
|
+
|
|
91
|
+
if (player.entry) {
|
|
92
|
+
setCurrentEntry(player.entry);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
setIsPaused(Boolean(player.isPaused()));
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
handleActivePlayerUpdate();
|
|
100
|
+
|
|
101
|
+
const removeLifecycle = playerManager.addLifecycleListener({
|
|
102
|
+
onRegistered: (registeredPlayer) => {
|
|
103
|
+
if (isPrimaryOrCastingPlayer(registeredPlayer)) {
|
|
104
|
+
handleActivePlayerUpdate();
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
onCastingChanged: handleActivePlayerUpdate,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return () => {
|
|
111
|
+
removeLifecycle?.();
|
|
112
|
+
};
|
|
113
|
+
}, []);
|
|
114
|
+
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
if (!activePlayer) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const syncPlayerState = () => {
|
|
121
|
+
if (activePlayer.entry) {
|
|
122
|
+
setCurrentEntry(activePlayer.entry);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
setIsPaused(Boolean(activePlayer.isPaused()));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
syncPlayerState();
|
|
129
|
+
|
|
130
|
+
const removeListener = activePlayer.addListener({
|
|
131
|
+
id: "queue-now-playing-header",
|
|
132
|
+
listener: {
|
|
133
|
+
onPlayerPause: () => setIsPaused(true),
|
|
134
|
+
onPlayerResume: () => setIsPaused(false),
|
|
135
|
+
onVideoLoad: syncPlayerState,
|
|
136
|
+
onLoad: syncPlayerState,
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return () => {
|
|
141
|
+
removeListener?.();
|
|
142
|
+
};
|
|
143
|
+
}, [activePlayer]);
|
|
144
|
+
|
|
145
|
+
const handlePlayPause = () => {
|
|
146
|
+
if (!activePlayer) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (isPaused) {
|
|
151
|
+
activePlayer.play();
|
|
152
|
+
setIsPaused(false);
|
|
153
|
+
} else {
|
|
154
|
+
activePlayer.pause();
|
|
155
|
+
setIsPaused(true);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
26
158
|
|
|
27
159
|
const renderNowPlayingTrack = () => {
|
|
28
|
-
if (!
|
|
160
|
+
if (!currentEntry) {
|
|
29
161
|
return null;
|
|
30
162
|
}
|
|
31
163
|
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const imageGroup = Array.isArray(mediaGroup)
|
|
35
|
-
? mediaGroup.find((g: any) => g.type === "image")
|
|
164
|
+
const imageGroup = Array.isArray(currentEntry.media_group)
|
|
165
|
+
? currentEntry.media_group.find((g: any) => g.type === "image")
|
|
36
166
|
: null;
|
|
37
167
|
|
|
38
168
|
const firstImage = Array.isArray(imageGroup?.media_item)
|
|
@@ -40,26 +170,18 @@ export function NowPlayingHeaderSection({
|
|
|
40
170
|
: imageGroup?.media_item?.src;
|
|
41
171
|
|
|
42
172
|
const nowPlayingItem: MenuItem = {
|
|
43
|
-
id: String(
|
|
44
|
-
title: (
|
|
45
|
-
summary: (
|
|
173
|
+
id: String(currentEntry.id ?? "now_playing"),
|
|
174
|
+
title: (currentEntry.title as string) || String(currentEntry.id),
|
|
175
|
+
summary: (currentEntry.summary as string) ?? "",
|
|
46
176
|
icon: firstImage,
|
|
47
177
|
};
|
|
48
178
|
|
|
49
179
|
const data = mapMenuItemToNowPlayingData(
|
|
50
180
|
nowPlayingItem,
|
|
51
|
-
|
|
181
|
+
isPaused,
|
|
52
182
|
nowPlayingTitle
|
|
53
183
|
);
|
|
54
184
|
|
|
55
|
-
const handlePlayPause = () => {
|
|
56
|
-
if (playerState?.isPaused) {
|
|
57
|
-
player?.play();
|
|
58
|
-
} else {
|
|
59
|
-
player?.pause();
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
185
|
return (
|
|
64
186
|
<AudioPlayerTrackItem
|
|
65
187
|
configuration={VARIANT_NOW_PLAYING}
|
|
@@ -74,9 +196,10 @@ export function NowPlayingHeaderSection({
|
|
|
74
196
|
{renderNowPlayingTrack()}
|
|
75
197
|
<AudioPlayerHeader
|
|
76
198
|
configuration={VARIANT_SECTION_HEADER}
|
|
77
|
-
data={{ title: nextUpTitle }}
|
|
199
|
+
data={{ title: nextUpTitle, clearLabel }}
|
|
78
200
|
onClear={onClear}
|
|
79
201
|
/>
|
|
202
|
+
{isEmpty ? <Text style={styles.emptyMessage}>{emptyMessage}</Text> : null}
|
|
80
203
|
</View>
|
|
81
204
|
);
|
|
82
205
|
}
|
package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react-native";
|
|
3
|
+
import { NowPlayingHeaderSection } from "../NowPlayingHeaderSection";
|
|
4
|
+
|
|
5
|
+
jest.mock(
|
|
6
|
+
"@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayer",
|
|
7
|
+
() => ({
|
|
8
|
+
usePlayer: () => null,
|
|
9
|
+
})
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
jest.mock(
|
|
13
|
+
"@applicaster/zapp-react-native-utils/appUtils/playerManager/usePlayerState",
|
|
14
|
+
() => ({
|
|
15
|
+
usePlayerState: () => ({ isPaused: true }),
|
|
16
|
+
})
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const EMPTY_COPY = "Queued items will be added here";
|
|
20
|
+
|
|
21
|
+
describe("NowPlayingHeaderSection empty queue", () => {
|
|
22
|
+
it("renders the empty message under Next Up when the list is empty", () => {
|
|
23
|
+
render(<NowPlayingHeaderSection isEmpty emptyMessage={EMPTY_COPY} />);
|
|
24
|
+
|
|
25
|
+
expect(screen.getByText("Next Up")).toBeTruthy();
|
|
26
|
+
expect(screen.getByText(EMPTY_COPY)).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("does not render the empty message when the list has items", () => {
|
|
30
|
+
render(
|
|
31
|
+
<NowPlayingHeaderSection isEmpty={false} emptyMessage={EMPTY_COPY} />
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
expect(screen.queryByText(EMPTY_COPY)).toBeNull();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
mergeItemConfiguration,
|
|
3
3
|
mergeButtonConfiguration,
|
|
4
|
+
mergeHeaderConfiguration,
|
|
4
5
|
} from "../mergeStyles";
|
|
6
|
+
import {
|
|
7
|
+
VARIANT_SECTION_HEADER,
|
|
8
|
+
VARIANT_SINGLE_LINE_HEADER,
|
|
9
|
+
} from "../../Components/Header";
|
|
5
10
|
|
|
6
11
|
const base = {
|
|
7
12
|
background: {
|
|
@@ -246,3 +251,106 @@ describe("mergeButtonConfiguration background", () => {
|
|
|
246
251
|
expect(merged.title.textTransform).toBe("uppercase");
|
|
247
252
|
});
|
|
248
253
|
});
|
|
254
|
+
|
|
255
|
+
describe("mergeHeaderConfiguration section header (Variant 3)", () => {
|
|
256
|
+
it("merges section title + Clear action button styles", () => {
|
|
257
|
+
const merged = mergeHeaderConfiguration(VARIANT_SECTION_HEADER, {
|
|
258
|
+
title: {
|
|
259
|
+
default: {
|
|
260
|
+
fontColor: "#ABCDEF",
|
|
261
|
+
fontSize: 15,
|
|
262
|
+
lineHeight: 36,
|
|
263
|
+
fontFamily: "CustomSection",
|
|
264
|
+
letterSpacing: -0.2,
|
|
265
|
+
textTransform: "uppercase",
|
|
266
|
+
alignment: "left",
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
actionButtons: {
|
|
270
|
+
default: {
|
|
271
|
+
backgroundColor: "rgba(10, 10, 10, 1)",
|
|
272
|
+
fontColor: "#EEEEEE",
|
|
273
|
+
fontSize: 12,
|
|
274
|
+
borderRadius: 20,
|
|
275
|
+
paddingTop: 8,
|
|
276
|
+
paddingRight: 12,
|
|
277
|
+
paddingBottom: 8,
|
|
278
|
+
paddingLeft: 12,
|
|
279
|
+
},
|
|
280
|
+
focused: {
|
|
281
|
+
backgroundColor: "rgba(20, 20, 20, 1)",
|
|
282
|
+
fontColor: "#FFDD00",
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
expect(merged.title.fontColor).toBe("#ABCDEF");
|
|
288
|
+
expect(merged.title.fontSize).toBe(15);
|
|
289
|
+
expect(merged.title.lineHeight).toBe(36);
|
|
290
|
+
expect(merged.title.iosFontFamily).toBe("CustomSection");
|
|
291
|
+
expect(merged.title.androidFontFamily).toBe("CustomSection");
|
|
292
|
+
expect(merged.title.iosLetterSpacing).toBe(-0.2);
|
|
293
|
+
expect(merged.title.textTransform).toBe("uppercase");
|
|
294
|
+
|
|
295
|
+
expect(merged.actionButtons.defaultBackgroundColor).toBe(
|
|
296
|
+
"rgba(10, 10, 10, 1)"
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
expect(merged.actionButtons.focusedBackgroundColor).toBe(
|
|
300
|
+
"rgba(20, 20, 20, 1)"
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
expect(merged.actionButtons.fontColor).toBe("#EEEEEE");
|
|
304
|
+
expect(merged.actionButtons.focusedFontColor).toBe("#FFDD00");
|
|
305
|
+
expect(merged.actionButtons.fontSize).toBe(12);
|
|
306
|
+
expect(merged.actionButtons.cornerRadius).toBe(20);
|
|
307
|
+
expect(merged.actionButtons.paddingTop).toBe(8);
|
|
308
|
+
expect(merged.actionButtons.paddingLeft).toBe(12);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("uses title.default when only platform font and letter spacing are set", () => {
|
|
312
|
+
const merged = mergeHeaderConfiguration(VARIANT_SECTION_HEADER, {
|
|
313
|
+
title: {
|
|
314
|
+
default: {
|
|
315
|
+
iosFontFamily: "SFProText-Semibold",
|
|
316
|
+
androidFontFamily: "Roboto-Medium",
|
|
317
|
+
iosLetterSpacing: -0.4,
|
|
318
|
+
androidLetterSpacing: 0,
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
expect(merged.title.iosFontFamily).toBe("SFProText-Semibold");
|
|
324
|
+
expect(merged.title.androidFontFamily).toBe("Roboto-Medium");
|
|
325
|
+
expect(merged.title.iosLetterSpacing).toBe(-0.4);
|
|
326
|
+
expect(merged.title.androidLetterSpacing).toBe(0);
|
|
327
|
+
expect(merged.title.fontSize).toBe(VARIANT_SECTION_HEADER.title.fontSize);
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
it("does not change section defaults when block is empty", () => {
|
|
331
|
+
const merged = mergeHeaderConfiguration(VARIANT_SECTION_HEADER, {
|
|
332
|
+
title: { default: {} },
|
|
333
|
+
actionButtons: { default: {} },
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
expect(merged.title.fontSize).toBe(VARIANT_SECTION_HEADER.title.fontSize);
|
|
337
|
+
|
|
338
|
+
expect(merged.actionButtons.defaultBackgroundColor).toBe(
|
|
339
|
+
VARIANT_SECTION_HEADER.actionButtons.defaultBackgroundColor
|
|
340
|
+
);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it("leaves single-line header title size untouched when only actionButtons set", () => {
|
|
344
|
+
const merged = mergeHeaderConfiguration(VARIANT_SINGLE_LINE_HEADER, {
|
|
345
|
+
actionButtons: {
|
|
346
|
+
default: { backgroundColor: "#123456" },
|
|
347
|
+
},
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
expect(merged.title.fontSize).toBe(
|
|
351
|
+
VARIANT_SINGLE_LINE_HEADER.title.fontSize
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
expect(merged.actionButtons.defaultBackgroundColor).toBe("#123456");
|
|
355
|
+
});
|
|
356
|
+
});
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
} from "../Components/Item";
|
|
10
10
|
import {
|
|
11
11
|
TitleConfiguration as HeaderTitleConfiguration,
|
|
12
|
+
ActionButtonsStyleConfiguration as HeaderActionButtonsStyleConfiguration,
|
|
12
13
|
HeaderConfiguration,
|
|
13
14
|
} from "../Components/Header";
|
|
14
15
|
import {
|
|
@@ -210,6 +211,122 @@ function mergeHeaderTitle(
|
|
|
210
211
|
...base,
|
|
211
212
|
...(override.fontColor ? { fontColor: override.fontColor } : {}),
|
|
212
213
|
...(override.fontSize !== undefined ? { fontSize: override.fontSize } : {}),
|
|
214
|
+
...(override.lineHeight !== undefined
|
|
215
|
+
? { lineHeight: override.lineHeight }
|
|
216
|
+
: {}),
|
|
217
|
+
...(typeof override.fontFamily === "string"
|
|
218
|
+
? {
|
|
219
|
+
iosFontFamily: override.fontFamily,
|
|
220
|
+
androidFontFamily: override.fontFamily,
|
|
221
|
+
}
|
|
222
|
+
: {}),
|
|
223
|
+
...(override.iosFontFamily
|
|
224
|
+
? { iosFontFamily: override.iosFontFamily }
|
|
225
|
+
: {}),
|
|
226
|
+
...(override.androidFontFamily
|
|
227
|
+
? { androidFontFamily: override.androidFontFamily }
|
|
228
|
+
: {}),
|
|
229
|
+
...(override.letterSpacing !== undefined
|
|
230
|
+
? {
|
|
231
|
+
iosLetterSpacing: override.letterSpacing,
|
|
232
|
+
androidLetterSpacing: override.letterSpacing,
|
|
233
|
+
}
|
|
234
|
+
: {}),
|
|
235
|
+
...(override.iosLetterSpacing !== undefined
|
|
236
|
+
? { iosLetterSpacing: override.iosLetterSpacing }
|
|
237
|
+
: {}),
|
|
238
|
+
...(override.androidLetterSpacing !== undefined
|
|
239
|
+
? { androidLetterSpacing: override.androidLetterSpacing }
|
|
240
|
+
: {}),
|
|
241
|
+
...(override.textTransform
|
|
242
|
+
? { textTransform: override.textTransform }
|
|
243
|
+
: {}),
|
|
244
|
+
...(override.alignment ? { alignment: override.alignment } : {}),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function mergeHeaderActionButtons(
|
|
249
|
+
base: HeaderActionButtonsStyleConfiguration,
|
|
250
|
+
defaultOverride?: Record<string, any>,
|
|
251
|
+
focusedOverride?: Record<string, any>
|
|
252
|
+
): HeaderActionButtonsStyleConfiguration {
|
|
253
|
+
if (!defaultOverride && !focusedOverride) return base;
|
|
254
|
+
|
|
255
|
+
const focusedBackgroundColor =
|
|
256
|
+
focusedOverride?.backgroundColor ??
|
|
257
|
+
defaultOverride?.focusBackgroundColor ??
|
|
258
|
+
defaultOverride?.focusedBackgroundColor;
|
|
259
|
+
|
|
260
|
+
const focusedFontColor =
|
|
261
|
+
focusedOverride?.fontColor ??
|
|
262
|
+
defaultOverride?.focusFontColor ??
|
|
263
|
+
defaultOverride?.focusedFontColor;
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
...base,
|
|
267
|
+
...(defaultOverride?.backgroundColor
|
|
268
|
+
? { defaultBackgroundColor: defaultOverride.backgroundColor }
|
|
269
|
+
: {}),
|
|
270
|
+
...(focusedBackgroundColor != null && focusedBackgroundColor !== ""
|
|
271
|
+
? { focusedBackgroundColor }
|
|
272
|
+
: {}),
|
|
273
|
+
...(defaultOverride?.fontColor
|
|
274
|
+
? { fontColor: defaultOverride.fontColor }
|
|
275
|
+
: {}),
|
|
276
|
+
...(focusedFontColor != null && focusedFontColor !== ""
|
|
277
|
+
? { focusedFontColor }
|
|
278
|
+
: {}),
|
|
279
|
+
...(defaultOverride?.fontSize !== undefined
|
|
280
|
+
? { fontSize: defaultOverride.fontSize }
|
|
281
|
+
: {}),
|
|
282
|
+
...(defaultOverride?.lineHeight !== undefined
|
|
283
|
+
? { lineHeight: defaultOverride.lineHeight }
|
|
284
|
+
: {}),
|
|
285
|
+
...(typeof defaultOverride?.fontFamily === "string"
|
|
286
|
+
? {
|
|
287
|
+
iosFontFamily: defaultOverride.fontFamily,
|
|
288
|
+
androidFontFamily: defaultOverride.fontFamily,
|
|
289
|
+
}
|
|
290
|
+
: {}),
|
|
291
|
+
...(defaultOverride?.iosFontFamily
|
|
292
|
+
? { iosFontFamily: defaultOverride.iosFontFamily }
|
|
293
|
+
: {}),
|
|
294
|
+
...(defaultOverride?.androidFontFamily
|
|
295
|
+
? { androidFontFamily: defaultOverride.androidFontFamily }
|
|
296
|
+
: {}),
|
|
297
|
+
...(defaultOverride?.letterSpacing !== undefined
|
|
298
|
+
? {
|
|
299
|
+
iosLetterSpacing: defaultOverride.letterSpacing,
|
|
300
|
+
androidLetterSpacing: defaultOverride.letterSpacing,
|
|
301
|
+
}
|
|
302
|
+
: {}),
|
|
303
|
+
...(defaultOverride?.iosLetterSpacing !== undefined
|
|
304
|
+
? { iosLetterSpacing: defaultOverride.iosLetterSpacing }
|
|
305
|
+
: {}),
|
|
306
|
+
...(defaultOverride?.androidLetterSpacing !== undefined
|
|
307
|
+
? { androidLetterSpacing: defaultOverride.androidLetterSpacing }
|
|
308
|
+
: {}),
|
|
309
|
+
...(defaultOverride?.textTransform
|
|
310
|
+
? { textTransform: defaultOverride.textTransform }
|
|
311
|
+
: {}),
|
|
312
|
+
...(defaultOverride?.borderRadius !== undefined
|
|
313
|
+
? { cornerRadius: defaultOverride.borderRadius }
|
|
314
|
+
: {}),
|
|
315
|
+
...(defaultOverride?.cornerRadius !== undefined
|
|
316
|
+
? { cornerRadius: defaultOverride.cornerRadius }
|
|
317
|
+
: {}),
|
|
318
|
+
...(defaultOverride?.paddingTop !== undefined
|
|
319
|
+
? { paddingTop: defaultOverride.paddingTop }
|
|
320
|
+
: {}),
|
|
321
|
+
...(defaultOverride?.paddingRight !== undefined
|
|
322
|
+
? { paddingRight: defaultOverride.paddingRight }
|
|
323
|
+
: {}),
|
|
324
|
+
...(defaultOverride?.paddingBottom !== undefined
|
|
325
|
+
? { paddingBottom: defaultOverride.paddingBottom }
|
|
326
|
+
: {}),
|
|
327
|
+
...(defaultOverride?.paddingLeft !== undefined
|
|
328
|
+
? { paddingLeft: defaultOverride.paddingLeft }
|
|
329
|
+
: {}),
|
|
213
330
|
};
|
|
214
331
|
}
|
|
215
332
|
|
|
@@ -221,9 +338,39 @@ export function mergeHeaderConfiguration(
|
|
|
221
338
|
|
|
222
339
|
const bgOverride = headerBlock.container?.default?.backgroundColor;
|
|
223
340
|
|
|
341
|
+
const actionButtonsDefault =
|
|
342
|
+
headerBlock.actionButtons?.default || headerBlock.actionButtons;
|
|
343
|
+
|
|
344
|
+
const actionButtonsFocused =
|
|
345
|
+
headerBlock.actionButtons?.focused || headerBlock.actionButtons?.focus;
|
|
346
|
+
|
|
347
|
+
// Parser shape is title.default.*; hydrate() returns a flat title object.
|
|
348
|
+
const titleDefault = headerBlock.title?.default;
|
|
349
|
+
|
|
350
|
+
const titleOverride =
|
|
351
|
+
titleDefault &&
|
|
352
|
+
(titleDefault.fontColor !== undefined ||
|
|
353
|
+
titleDefault.fontSize !== undefined ||
|
|
354
|
+
titleDefault.lineHeight !== undefined ||
|
|
355
|
+
titleDefault.fontFamily ||
|
|
356
|
+
titleDefault.iosFontFamily ||
|
|
357
|
+
titleDefault.androidFontFamily ||
|
|
358
|
+
titleDefault.letterSpacing !== undefined ||
|
|
359
|
+
titleDefault.iosLetterSpacing !== undefined ||
|
|
360
|
+
titleDefault.androidLetterSpacing !== undefined ||
|
|
361
|
+
titleDefault.textTransform ||
|
|
362
|
+
titleDefault.alignment)
|
|
363
|
+
? titleDefault
|
|
364
|
+
: headerBlock.title;
|
|
365
|
+
|
|
224
366
|
return {
|
|
225
367
|
...base,
|
|
226
|
-
title: mergeHeaderTitle(base.title,
|
|
368
|
+
title: mergeHeaderTitle(base.title, titleOverride),
|
|
369
|
+
actionButtons: mergeHeaderActionButtons(
|
|
370
|
+
base.actionButtons,
|
|
371
|
+
actionButtonsDefault,
|
|
372
|
+
actionButtonsFocused
|
|
373
|
+
),
|
|
227
374
|
...(bgOverride ? { backgroundColor: bgOverride } : {}),
|
|
228
375
|
};
|
|
229
376
|
}
|