@applicaster/zapp-react-native-ui-components 15.1.10 → 15.1.11-alpha.2710844646
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/ActionsBottomSheet/ActionButton.tsx +54 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +21 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +58 -0
- package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +33 -87
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +42 -71
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +142 -107
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +653 -0
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +319 -154
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +89 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +8 -4
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +199 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +379 -61
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/index.tsx +20 -7
- package/Components/ModalComponent/Header/utils.ts +1 -1
- package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
- package/Components/ModalComponent/SortableList.tsx +142 -0
- package/Components/ModalComponent/SortableList.web.tsx +102 -0
- package/Components/ModalComponent/TextInputContent.tsx +100 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +238 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +120 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
- package/Components/ModalComponent/index.tsx +11 -0
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +66 -0
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
- package/Components/ModalComponent/presets/index.ts +27 -0
- package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
- package/Components/ModalComponent/presets/standardCell.tsx +41 -0
- package/Components/ModalComponent/presets/types.ts +35 -0
- package/Components/ModalComponent/showTextInput.ts +43 -0
- package/Components/ModalComponent/utils.ts +76 -20
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/package.json +6 -5
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
|
@@ -12,7 +12,20 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import React from "react";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
Image,
|
|
17
|
+
Platform,
|
|
18
|
+
Pressable,
|
|
19
|
+
StyleSheet,
|
|
20
|
+
Text,
|
|
21
|
+
View,
|
|
22
|
+
} from "react-native";
|
|
23
|
+
import {
|
|
24
|
+
MenuItem,
|
|
25
|
+
SelectionBehavior,
|
|
26
|
+
} from "@applicaster/zapp-react-native-utils/modalState/types";
|
|
27
|
+
import { useModalBlocksStyle } from "../../ModalBlocksStyleContext";
|
|
28
|
+
import { mergeItemConfiguration } from "../utils/mergeStyles";
|
|
16
29
|
|
|
17
30
|
const styles = StyleSheet.create({
|
|
18
31
|
row: {
|
|
@@ -27,25 +40,6 @@ const styles = StyleSheet.create({
|
|
|
27
40
|
flexDirection: "row",
|
|
28
41
|
alignItems: "center",
|
|
29
42
|
},
|
|
30
|
-
demoScreen: {
|
|
31
|
-
flex: 1,
|
|
32
|
-
backgroundColor: "#1C1C1E",
|
|
33
|
-
paddingTop: 64,
|
|
34
|
-
paddingHorizontal: 0,
|
|
35
|
-
gap: 16,
|
|
36
|
-
},
|
|
37
|
-
demoHeading: {
|
|
38
|
-
color: "#FFFFFF",
|
|
39
|
-
fontSize: 20,
|
|
40
|
-
fontWeight: "600",
|
|
41
|
-
marginBottom: 8,
|
|
42
|
-
paddingHorizontal: 16,
|
|
43
|
-
},
|
|
44
|
-
demoLabel: {
|
|
45
|
-
color: "#999999",
|
|
46
|
-
fontSize: 13,
|
|
47
|
-
paddingHorizontal: 16,
|
|
48
|
-
},
|
|
49
43
|
});
|
|
50
44
|
|
|
51
45
|
// ---------------------------------------------------------------------------
|
|
@@ -97,50 +91,6 @@ export type ItemConfiguration = {
|
|
|
97
91
|
textLabel2: LabelConfiguration;
|
|
98
92
|
};
|
|
99
93
|
|
|
100
|
-
export interface Action {
|
|
101
|
-
type: string;
|
|
102
|
-
payload?: any;
|
|
103
|
-
options?: any;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
export interface Header {
|
|
107
|
-
title: string;
|
|
108
|
-
subtitle?: string;
|
|
109
|
-
icon?: string;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export interface Content {
|
|
113
|
-
title: string;
|
|
114
|
-
stickyTitle?: boolean;
|
|
115
|
-
items: MenuItem[];
|
|
116
|
-
itemsUrl?: string;
|
|
117
|
-
action?: Action;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
export interface Menu {
|
|
121
|
-
header?: Header;
|
|
122
|
-
content: Content;
|
|
123
|
-
closeButton?: boolean;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export interface PresentSubMenuAction extends Action {
|
|
127
|
-
menu: Menu;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export interface SecondaryAction {
|
|
131
|
-
action: Action | PresentSubMenuAction;
|
|
132
|
-
icon?: string;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export interface MenuItem {
|
|
136
|
-
title: string;
|
|
137
|
-
summary?: string;
|
|
138
|
-
icon?: string;
|
|
139
|
-
isSelected?: boolean;
|
|
140
|
-
action?: Action | PresentSubMenuAction;
|
|
141
|
-
secondaryAction?: SecondaryAction;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
94
|
export const DEFAULT_TEXT_LABEL_1_CONFIGURATION: LabelConfiguration = {
|
|
145
95
|
fontColor: "#FFFFFF",
|
|
146
96
|
focusedFontColor: "#FFFFFF",
|
|
@@ -191,14 +141,19 @@ export type ItemData = {
|
|
|
191
141
|
leadingButton?: ItemButtonAction;
|
|
192
142
|
/** Button 1 (right most) — hardcoded action decides icon. */
|
|
193
143
|
trailingButton?: ItemButtonAction;
|
|
144
|
+
isSelected?: boolean;
|
|
194
145
|
};
|
|
195
146
|
|
|
196
|
-
export type
|
|
147
|
+
export type AudioPlayerTrackItemProps = {
|
|
197
148
|
configuration: ItemConfiguration;
|
|
198
149
|
data: ItemData;
|
|
199
150
|
focused?: boolean;
|
|
200
151
|
focusedLeadingButton?: boolean;
|
|
201
152
|
focusedTrailingButton?: boolean;
|
|
153
|
+
onPress?: () => void;
|
|
154
|
+
onLeadingButtonPress?: () => void;
|
|
155
|
+
onTrailingButtonPress?: () => void;
|
|
156
|
+
renderHandle?: (element: React.ReactElement) => React.ReactElement;
|
|
202
157
|
};
|
|
203
158
|
|
|
204
159
|
// ---------------------------------------------------------------------------
|
|
@@ -234,9 +189,9 @@ const CONTAINER_SPEC_LARGE_IMAGE: ContainerSpec = {
|
|
|
234
189
|
|
|
235
190
|
const CONTAINER_SPEC_DEFAULT: ContainerSpec = {
|
|
236
191
|
paddingTop: 8,
|
|
237
|
-
paddingRight:
|
|
192
|
+
paddingRight: 20,
|
|
238
193
|
paddingBottom: 8,
|
|
239
|
-
paddingLeft:
|
|
194
|
+
paddingLeft: 20,
|
|
240
195
|
horizontalGutter: 12,
|
|
241
196
|
verticalGutter: 2,
|
|
242
197
|
};
|
|
@@ -297,16 +252,6 @@ const DEFAULT_THUMB_ASSET =
|
|
|
297
252
|
const DEFAULT_EQUALIZER_ASSET =
|
|
298
253
|
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAI0lEQVR42mNgGNTgPxTQzwB0DVQ3gKCBowbQwYAhkBIHBAAA9TvPMeOFaLMAAAAASUVORK5CYII=";
|
|
299
254
|
|
|
300
|
-
const BUTTON_ASSETS: Record<ItemButtonAction, string> = {
|
|
301
|
-
playPause:
|
|
302
|
-
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAYAAAAehFoBAAAAdklEQVR42u3ZwRUAERAEUfkn3TaF5TFTrSuCf3CgjZGg6ast7G8YaAlcB8JAj8F1MRR2G63CUNglNAqsRvmB1TAfsBoXcMABV4MFKEci4IADNrkAed2H80R66SHqvUvglh/ktoZcL5H7MHKBx/5xYH+RsP90t5t2UpF6+22a+AAAAABJRU5ErkJggg==",
|
|
303
|
-
drag: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAIklEQVR42mNgGAWjYGiC/2SCwWPBaByMxsFoHIyCUTDYAAAqhk7AVXdZJwAAAABJRU5ErkJggg==",
|
|
304
|
-
multiSelect:
|
|
305
|
-
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAWklEQVR42t2VUQ4AIAhCvf+lrQsULJJZbH7GM1cS0Uk5dd0Qqcz4GJSCSs0pSCkAHNoWBfkTgIxpgGK+ujyEKABqRGyn9FO1A+yfrf+qsGxTSx5YEs2WyU9oAKBJKg8Kfq4dAAAAAElFTkSuQmCC",
|
|
306
|
-
remove:
|
|
307
|
-
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAUklEQVR42mNgGPbgPx5AVYOJlSPJcGqrJU8DKXooCVui9FIacXj1UyNl4DWDLhYgc8nA+INpeFgwtCOZ5vmALjmZ5mURXUpTutQHdKnRRgEMAACwjWWprU1B+AAAAABJRU5ErkJggg==",
|
|
308
|
-
};
|
|
309
|
-
|
|
310
255
|
function getTextTransformStyle(
|
|
311
256
|
textTransform: TextTransform
|
|
312
257
|
): "none" | "lowercase" | "uppercase" | "capitalize" {
|
|
@@ -324,32 +269,46 @@ function resolveContainerSpec(image: ImageConfiguration): ContainerSpec {
|
|
|
324
269
|
: CONTAINER_SPEC_DEFAULT;
|
|
325
270
|
}
|
|
326
271
|
|
|
327
|
-
function mapMenuItemToNowPlayingData(
|
|
272
|
+
export function mapMenuItemToNowPlayingData(
|
|
273
|
+
item: MenuItem,
|
|
274
|
+
isPaused?: boolean
|
|
275
|
+
): ItemData {
|
|
328
276
|
return {
|
|
329
277
|
imageUri: item.icon,
|
|
330
278
|
textLabel1: item.title,
|
|
331
279
|
textLabel2: item.summary ?? "",
|
|
332
280
|
nowPlayingLabel: "Now Playing",
|
|
333
281
|
trailingButton: "playPause",
|
|
282
|
+
isSelected: isPaused !== undefined ? !isPaused : item.isSelected,
|
|
334
283
|
};
|
|
335
284
|
}
|
|
336
285
|
|
|
337
|
-
function mapMenuItemToQueuedData(item: MenuItem): ItemData {
|
|
286
|
+
export function mapMenuItemToQueuedData(item: MenuItem): ItemData {
|
|
338
287
|
return {
|
|
339
288
|
imageUri: item.icon,
|
|
340
289
|
textLabel1: item.title,
|
|
341
290
|
textLabel2: item.summary ?? "",
|
|
342
291
|
leadingButton: "remove",
|
|
343
292
|
trailingButton: "drag",
|
|
293
|
+
isSelected: item.isSelected,
|
|
344
294
|
};
|
|
345
295
|
}
|
|
346
296
|
|
|
347
|
-
function mapMenuItemToPlaylistData(
|
|
297
|
+
export function mapMenuItemToPlaylistData(
|
|
298
|
+
item: MenuItem,
|
|
299
|
+
behavior?: SelectionBehavior
|
|
300
|
+
): ItemData {
|
|
301
|
+
const showSelectionWidget =
|
|
302
|
+
behavior?.selectMode !== "none" && item.trailingButton !== "none";
|
|
303
|
+
|
|
348
304
|
return {
|
|
349
305
|
imageUri: item.icon,
|
|
350
306
|
textLabel1: item.title,
|
|
351
307
|
textLabel2: item.summary ?? "",
|
|
352
|
-
trailingButton:
|
|
308
|
+
trailingButton: showSelectionWidget
|
|
309
|
+
? item.trailingButton || ("multiSelect" as ItemButtonAction)
|
|
310
|
+
: undefined,
|
|
311
|
+
isSelected: item.isSelected,
|
|
353
312
|
};
|
|
354
313
|
}
|
|
355
314
|
|
|
@@ -362,6 +321,7 @@ type ItemContainerProps = {
|
|
|
362
321
|
background: BackgroundConfiguration;
|
|
363
322
|
focused: boolean;
|
|
364
323
|
children: React.ReactNode;
|
|
324
|
+
onPress?: () => void;
|
|
365
325
|
};
|
|
366
326
|
|
|
367
327
|
function ItemContainer({
|
|
@@ -369,23 +329,25 @@ function ItemContainer({
|
|
|
369
329
|
background,
|
|
370
330
|
focused,
|
|
371
331
|
children,
|
|
332
|
+
onPress,
|
|
372
333
|
}: ItemContainerProps) {
|
|
373
334
|
const container = resolveContainerSpec(image);
|
|
374
335
|
const bg = focused ? background.focusedColor : background.defaultColor;
|
|
375
336
|
|
|
376
337
|
return (
|
|
377
|
-
<
|
|
378
|
-
|
|
379
|
-
|
|
338
|
+
<Pressable
|
|
339
|
+
onPress={onPress}
|
|
340
|
+
style={({ pressed }) => ({
|
|
341
|
+
backgroundColor: pressed ? background.focusedColor : bg,
|
|
380
342
|
borderRadius: background.cornerRadius,
|
|
381
343
|
paddingTop: container.paddingTop,
|
|
382
344
|
paddingRight: container.paddingRight,
|
|
383
345
|
paddingBottom: container.paddingBottom,
|
|
384
346
|
paddingLeft: container.paddingLeft,
|
|
385
|
-
}}
|
|
347
|
+
})}
|
|
386
348
|
>
|
|
387
349
|
{children}
|
|
388
|
-
</
|
|
350
|
+
</Pressable>
|
|
389
351
|
);
|
|
390
352
|
}
|
|
391
353
|
|
|
@@ -486,27 +448,212 @@ function NowPlayingRow({
|
|
|
486
448
|
type ItemButtonProps = {
|
|
487
449
|
action: ItemButtonAction;
|
|
488
450
|
focused?: boolean;
|
|
451
|
+
onPress?: () => void;
|
|
452
|
+
isSelected?: boolean;
|
|
489
453
|
};
|
|
490
454
|
|
|
491
|
-
function ItemButton({
|
|
455
|
+
function ItemButton({
|
|
456
|
+
action,
|
|
457
|
+
focused = false,
|
|
458
|
+
onPress,
|
|
459
|
+
isSelected = false,
|
|
460
|
+
}: ItemButtonProps) {
|
|
492
461
|
const layout = BUTTON_LAYOUT_SPEC[action];
|
|
493
462
|
|
|
463
|
+
if (!layout) {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
const renderIcon = () => {
|
|
468
|
+
switch (action) {
|
|
469
|
+
case "playPause": {
|
|
470
|
+
const iconSize = layout.assetWidth;
|
|
471
|
+
const iconRadius = iconSize / 2;
|
|
472
|
+
|
|
473
|
+
return (
|
|
474
|
+
<View
|
|
475
|
+
style={{
|
|
476
|
+
width: iconSize,
|
|
477
|
+
height: iconSize,
|
|
478
|
+
borderRadius: iconRadius,
|
|
479
|
+
backgroundColor: "#FFFFFF",
|
|
480
|
+
justifyContent: "center",
|
|
481
|
+
alignItems: "center",
|
|
482
|
+
}}
|
|
483
|
+
>
|
|
484
|
+
{isSelected ? (
|
|
485
|
+
<View
|
|
486
|
+
style={{
|
|
487
|
+
flexDirection: "row",
|
|
488
|
+
justifyContent: "space-between",
|
|
489
|
+
width: 10,
|
|
490
|
+
height: 16,
|
|
491
|
+
}}
|
|
492
|
+
>
|
|
493
|
+
<View
|
|
494
|
+
style={{
|
|
495
|
+
width: 3.5,
|
|
496
|
+
height: 16,
|
|
497
|
+
backgroundColor: "#1e1e1e",
|
|
498
|
+
borderRadius: 1,
|
|
499
|
+
}}
|
|
500
|
+
/>
|
|
501
|
+
<View
|
|
502
|
+
style={{
|
|
503
|
+
width: 3.5,
|
|
504
|
+
height: 16,
|
|
505
|
+
backgroundColor: "#1e1e1e",
|
|
506
|
+
borderRadius: 1,
|
|
507
|
+
}}
|
|
508
|
+
/>
|
|
509
|
+
</View>
|
|
510
|
+
) : (
|
|
511
|
+
<View
|
|
512
|
+
style={{
|
|
513
|
+
width: 0,
|
|
514
|
+
height: 0,
|
|
515
|
+
backgroundColor: "transparent",
|
|
516
|
+
borderStyle: "solid",
|
|
517
|
+
borderLeftWidth: 14,
|
|
518
|
+
borderRightWidth: 0,
|
|
519
|
+
borderTopWidth: 8,
|
|
520
|
+
borderBottomWidth: 8,
|
|
521
|
+
borderLeftColor: "#1e1e1e",
|
|
522
|
+
borderRightColor: "transparent",
|
|
523
|
+
borderTopColor: "transparent",
|
|
524
|
+
borderBottomColor: "transparent",
|
|
525
|
+
marginLeft: 3,
|
|
526
|
+
}}
|
|
527
|
+
/>
|
|
528
|
+
)}
|
|
529
|
+
</View>
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
case "drag": {
|
|
534
|
+
return (
|
|
535
|
+
<View
|
|
536
|
+
style={{
|
|
537
|
+
width: 20,
|
|
538
|
+
height: 12,
|
|
539
|
+
justifyContent: "space-between",
|
|
540
|
+
}}
|
|
541
|
+
>
|
|
542
|
+
<View
|
|
543
|
+
style={{
|
|
544
|
+
height: 2,
|
|
545
|
+
backgroundColor: "rgba(255, 255, 255, 0.7)",
|
|
546
|
+
borderRadius: 1,
|
|
547
|
+
}}
|
|
548
|
+
/>
|
|
549
|
+
<View
|
|
550
|
+
style={{
|
|
551
|
+
height: 2,
|
|
552
|
+
backgroundColor: "rgba(255, 255, 255, 0.7)",
|
|
553
|
+
borderRadius: 1,
|
|
554
|
+
}}
|
|
555
|
+
/>
|
|
556
|
+
<View
|
|
557
|
+
style={{
|
|
558
|
+
height: 2,
|
|
559
|
+
backgroundColor: "rgba(255, 255, 255, 0.7)",
|
|
560
|
+
borderRadius: 1,
|
|
561
|
+
}}
|
|
562
|
+
/>
|
|
563
|
+
</View>
|
|
564
|
+
);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
case "remove": {
|
|
568
|
+
return (
|
|
569
|
+
<View
|
|
570
|
+
style={{
|
|
571
|
+
width: 24,
|
|
572
|
+
height: 24,
|
|
573
|
+
borderRadius: 12,
|
|
574
|
+
borderWidth: 1.5,
|
|
575
|
+
borderColor: "rgba(255, 255, 255, 0.7)",
|
|
576
|
+
justifyContent: "center",
|
|
577
|
+
alignItems: "center",
|
|
578
|
+
}}
|
|
579
|
+
>
|
|
580
|
+
<View
|
|
581
|
+
style={{
|
|
582
|
+
width: 10,
|
|
583
|
+
height: 1.5,
|
|
584
|
+
backgroundColor: "rgba(255, 255, 255, 0.7)",
|
|
585
|
+
borderRadius: 1,
|
|
586
|
+
}}
|
|
587
|
+
/>
|
|
588
|
+
</View>
|
|
589
|
+
);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
case "multiSelect": {
|
|
593
|
+
if (!isSelected) {
|
|
594
|
+
return (
|
|
595
|
+
<View
|
|
596
|
+
style={{
|
|
597
|
+
width: layout.assetWidth,
|
|
598
|
+
height: layout.assetHeight,
|
|
599
|
+
borderRadius: layout.assetWidth / 2,
|
|
600
|
+
borderWidth: 1.5,
|
|
601
|
+
borderColor: "rgba(255, 255, 255, 0.7)",
|
|
602
|
+
backgroundColor: "transparent",
|
|
603
|
+
}}
|
|
604
|
+
/>
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
return (
|
|
609
|
+
<View
|
|
610
|
+
style={{
|
|
611
|
+
width: 24,
|
|
612
|
+
height: 24,
|
|
613
|
+
borderRadius: 12,
|
|
614
|
+
backgroundColor: "#FFFFFF",
|
|
615
|
+
justifyContent: "center",
|
|
616
|
+
alignItems: "center",
|
|
617
|
+
}}
|
|
618
|
+
>
|
|
619
|
+
<View
|
|
620
|
+
style={{
|
|
621
|
+
width: 6,
|
|
622
|
+
height: 10,
|
|
623
|
+
borderBottomWidth: 2,
|
|
624
|
+
borderRightWidth: 2,
|
|
625
|
+
borderColor: "#1e1e1e",
|
|
626
|
+
transform: [{ rotate: "45deg" }],
|
|
627
|
+
marginTop: -2,
|
|
628
|
+
}}
|
|
629
|
+
/>
|
|
630
|
+
</View>
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
default:
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
};
|
|
638
|
+
|
|
494
639
|
return (
|
|
495
|
-
<
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
paddingBottom: layout.paddingBottom,
|
|
500
|
-
paddingLeft: layout.paddingLeft,
|
|
501
|
-
opacity: focused ? 0.7 : 1,
|
|
640
|
+
<Pressable
|
|
641
|
+
onPress={(e: any) => {
|
|
642
|
+
e?.stopPropagation?.();
|
|
643
|
+
onPress?.();
|
|
502
644
|
}}
|
|
645
|
+
style={({ pressed }) => [
|
|
646
|
+
{
|
|
647
|
+
paddingTop: layout.paddingTop,
|
|
648
|
+
paddingRight: layout.paddingRight,
|
|
649
|
+
paddingBottom: layout.paddingBottom,
|
|
650
|
+
paddingLeft: layout.paddingLeft,
|
|
651
|
+
opacity: pressed || focused ? 0.7 : 1,
|
|
652
|
+
},
|
|
653
|
+
]}
|
|
503
654
|
>
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
style={{ width: layout.assetWidth, height: layout.assetHeight }}
|
|
507
|
-
resizeMode="contain"
|
|
508
|
-
/>
|
|
509
|
-
</View>
|
|
655
|
+
{renderIcon()}
|
|
656
|
+
</Pressable>
|
|
510
657
|
);
|
|
511
658
|
}
|
|
512
659
|
|
|
@@ -515,6 +662,10 @@ type ItemButtonsProps = {
|
|
|
515
662
|
trailingButton?: ItemButtonAction;
|
|
516
663
|
focusedLeadingButton?: boolean;
|
|
517
664
|
focusedTrailingButton?: boolean;
|
|
665
|
+
onLeadingButtonPress?: () => void;
|
|
666
|
+
onTrailingButtonPress?: () => void;
|
|
667
|
+
isSelected?: boolean;
|
|
668
|
+
renderHandle?: (element: React.ReactElement) => React.ReactElement;
|
|
518
669
|
};
|
|
519
670
|
|
|
520
671
|
function ItemButtons({
|
|
@@ -522,6 +673,10 @@ function ItemButtons({
|
|
|
522
673
|
trailingButton,
|
|
523
674
|
focusedLeadingButton = false,
|
|
524
675
|
focusedTrailingButton = false,
|
|
676
|
+
onLeadingButtonPress,
|
|
677
|
+
onTrailingButtonPress,
|
|
678
|
+
isSelected = false,
|
|
679
|
+
renderHandle,
|
|
525
680
|
}: ItemButtonsProps) {
|
|
526
681
|
if (!leadingButton && !trailingButton) {
|
|
527
682
|
return null;
|
|
@@ -531,42 +686,92 @@ function ItemButtons({
|
|
|
531
686
|
<View style={styles.buttonsRow}>
|
|
532
687
|
{leadingButton ? (
|
|
533
688
|
<>
|
|
534
|
-
<ItemButton
|
|
689
|
+
<ItemButton
|
|
690
|
+
action={leadingButton}
|
|
691
|
+
focused={focusedLeadingButton}
|
|
692
|
+
onPress={onLeadingButtonPress}
|
|
693
|
+
isSelected={isSelected}
|
|
694
|
+
/>
|
|
535
695
|
<View style={{ width: BUTTONS_CONTAINER_HORIZONTAL_GUTTER }} />
|
|
536
696
|
</>
|
|
537
697
|
) : null}
|
|
538
698
|
{trailingButton ? (
|
|
539
|
-
|
|
699
|
+
trailingButton === "drag" ? (
|
|
700
|
+
renderHandle ? (
|
|
701
|
+
renderHandle(
|
|
702
|
+
<ItemButton
|
|
703
|
+
action={trailingButton}
|
|
704
|
+
focused={focusedTrailingButton}
|
|
705
|
+
onPress={onTrailingButtonPress}
|
|
706
|
+
isSelected={isSelected}
|
|
707
|
+
/>
|
|
708
|
+
)
|
|
709
|
+
) : (
|
|
710
|
+
<ItemButton
|
|
711
|
+
action={trailingButton}
|
|
712
|
+
focused={focusedTrailingButton}
|
|
713
|
+
onPress={onTrailingButtonPress}
|
|
714
|
+
isSelected={isSelected}
|
|
715
|
+
/>
|
|
716
|
+
)
|
|
717
|
+
) : (
|
|
718
|
+
<ItemButton
|
|
719
|
+
action={trailingButton}
|
|
720
|
+
focused={focusedTrailingButton}
|
|
721
|
+
onPress={onTrailingButtonPress}
|
|
722
|
+
isSelected={isSelected}
|
|
723
|
+
/>
|
|
724
|
+
)
|
|
540
725
|
) : null}
|
|
541
726
|
</View>
|
|
542
727
|
);
|
|
543
728
|
}
|
|
544
729
|
|
|
545
730
|
// ---------------------------------------------------------------------------
|
|
546
|
-
//
|
|
731
|
+
// AudioPlayerTrackItem
|
|
547
732
|
// ---------------------------------------------------------------------------
|
|
548
733
|
|
|
549
|
-
export function
|
|
734
|
+
export function AudioPlayerTrackItem({
|
|
550
735
|
configuration,
|
|
551
736
|
data,
|
|
552
737
|
focused = false,
|
|
553
738
|
focusedLeadingButton = false,
|
|
554
739
|
focusedTrailingButton = false,
|
|
555
|
-
|
|
740
|
+
onPress,
|
|
741
|
+
onLeadingButtonPress,
|
|
742
|
+
onTrailingButtonPress,
|
|
743
|
+
renderHandle,
|
|
744
|
+
}: AudioPlayerTrackItemProps) {
|
|
745
|
+
const modalBlocksStyle = useModalBlocksStyle();
|
|
746
|
+
const showNowPlaying = !!data.nowPlayingLabel;
|
|
747
|
+
|
|
748
|
+
const itemBlock =
|
|
749
|
+
showNowPlaying && modalBlocksStyle?.nowPlayingItem
|
|
750
|
+
? modalBlocksStyle.nowPlayingItem
|
|
751
|
+
: modalBlocksStyle?.item;
|
|
752
|
+
|
|
753
|
+
const effectiveConfig = React.useMemo(() => {
|
|
754
|
+
return mergeItemConfiguration(configuration, itemBlock);
|
|
755
|
+
}, [configuration, itemBlock]);
|
|
756
|
+
|
|
556
757
|
const {
|
|
557
758
|
background,
|
|
558
759
|
image,
|
|
559
|
-
nowPlayingAsset,
|
|
560
|
-
nowPlayingLabel,
|
|
561
760
|
textLabel1,
|
|
562
761
|
textLabel2,
|
|
563
|
-
|
|
762
|
+
nowPlayingLabel,
|
|
763
|
+
nowPlayingAsset,
|
|
764
|
+
} = effectiveConfig;
|
|
564
765
|
|
|
565
766
|
const container = resolveContainerSpec(image);
|
|
566
|
-
const showNowPlaying = !!data.nowPlayingLabel;
|
|
567
767
|
|
|
568
768
|
return (
|
|
569
|
-
<ItemContainer
|
|
769
|
+
<ItemContainer
|
|
770
|
+
image={image}
|
|
771
|
+
background={background}
|
|
772
|
+
focused={focused}
|
|
773
|
+
onPress={onPress}
|
|
774
|
+
>
|
|
570
775
|
<View style={styles.row}>
|
|
571
776
|
<ItemThumbnail configuration={image} imageUri={data.imageUri} />
|
|
572
777
|
<View style={{ width: container.horizontalGutter }} />
|
|
@@ -594,6 +799,10 @@ export function Item({
|
|
|
594
799
|
trailingButton={data.trailingButton}
|
|
595
800
|
focusedLeadingButton={focusedLeadingButton}
|
|
596
801
|
focusedTrailingButton={focusedTrailingButton}
|
|
802
|
+
onLeadingButtonPress={onLeadingButtonPress}
|
|
803
|
+
onTrailingButtonPress={onTrailingButtonPress}
|
|
804
|
+
isSelected={data.isSelected}
|
|
805
|
+
renderHandle={renderHandle}
|
|
597
806
|
/>
|
|
598
807
|
</View>
|
|
599
808
|
</ItemContainer>
|
|
@@ -663,47 +872,3 @@ export const VARIANT_PLAYLIST_ITEM: ItemConfiguration = {
|
|
|
663
872
|
textLabel1: DEFAULT_TEXT_LABEL_1_CONFIGURATION,
|
|
664
873
|
textLabel2: DEFAULT_TEXT_LABEL_2_CONFIGURATION,
|
|
665
874
|
};
|
|
666
|
-
|
|
667
|
-
export default function App() {
|
|
668
|
-
// Hardcoded core mock data objects matching user types framework
|
|
669
|
-
const sharedMockItem: MenuItem = {
|
|
670
|
-
title: "Content Title",
|
|
671
|
-
summary: "Artist",
|
|
672
|
-
icon: "https://picsum.photos/200",
|
|
673
|
-
action: { type: "PLAY_AUDIO" },
|
|
674
|
-
secondaryAction: { action: { type: "OPEN_CONTEXT_MENU" } },
|
|
675
|
-
};
|
|
676
|
-
|
|
677
|
-
const playlistMockItem: MenuItem = {
|
|
678
|
-
title: "Playlist Name",
|
|
679
|
-
summary: "12 Songs",
|
|
680
|
-
icon: "https://picsum.photos/201",
|
|
681
|
-
isSelected: true,
|
|
682
|
-
action: { type: "NAVIGATE_PLAYLIST" },
|
|
683
|
-
};
|
|
684
|
-
|
|
685
|
-
return (
|
|
686
|
-
<View style={styles.demoScreen}>
|
|
687
|
-
<Text style={styles.demoHeading}>Modal Item Building Block</Text>
|
|
688
|
-
|
|
689
|
-
<Text style={styles.demoLabel}>Now Playing</Text>
|
|
690
|
-
<Item
|
|
691
|
-
configuration={VARIANT_NOW_PLAYING}
|
|
692
|
-
data={mapMenuItemToNowPlayingData(sharedMockItem)}
|
|
693
|
-
/>
|
|
694
|
-
|
|
695
|
-
<Text style={styles.demoLabel}>Queued Item</Text>
|
|
696
|
-
<Item
|
|
697
|
-
configuration={VARIANT_QUEUED_ITEM}
|
|
698
|
-
data={mapMenuItemToQueuedData(sharedMockItem)}
|
|
699
|
-
focused
|
|
700
|
-
/>
|
|
701
|
-
|
|
702
|
-
<Text style={styles.demoLabel}>Playlist Item</Text>
|
|
703
|
-
<Item
|
|
704
|
-
configuration={VARIANT_PLAYLIST_ITEM}
|
|
705
|
-
data={mapMenuItemToPlaylistData(playlistMockItem)}
|
|
706
|
-
/>
|
|
707
|
-
</View>
|
|
708
|
-
);
|
|
709
|
-
}
|