@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1453660071 → 16.0.0-alpha.1454930193
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/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
- package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
- package/Components/AudioPlayer/tv/index.tsx +5 -1
- package/Components/Cell/Cell.tsx +3 -6
- package/Components/Cell/TvOSCellComponent.tsx +0 -1
- package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +15 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +64 -0
- package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
- package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +18 -0
- package/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +5 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +47 -21
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +34 -6
- package/Components/MasterCell/DefaultComponents/Button.tsx +1 -0
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +5 -3
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/PressableView.tsx +29 -9
- package/Components/MasterCell/DefaultComponents/Text/hooks/useText.ts +4 -0
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
- package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +154 -100
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +56 -22
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +6 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +3 -1
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +32 -21
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +15 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +23 -16
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +8 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +45 -13
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -2
- package/Components/MasterCell/contexts/PressedStateContext.ts +3 -0
- package/Components/MasterCell/hooks/index.ts +2 -0
- package/Components/MasterCell/hooks/usePressedState.ts +4 -0
- package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
- package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +392 -0
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +772 -0
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +728 -0
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +1007 -0
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +113 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +9 -0
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +356 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +521 -0
- package/Components/ModalComponent/BottomSheetDragArea.tsx +33 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +505 -50
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
- package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
- 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 +156 -0
- package/Components/ModalComponent/SortableList.web.tsx +34 -0
- package/Components/ModalComponent/TextInputContent.tsx +135 -0
- package/Components/ModalComponent/__tests__/BottomSheetDragArea.test.tsx +74 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
- package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
- package/Components/ModalComponent/index.tsx +18 -9
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -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 +52 -0
- package/Components/ModalComponent/utils.ts +82 -21
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +4 -85
- package/Components/OfflineHandler/__tests__/index.test.tsx +78 -18
- package/Components/OfflineHandler/hooks.ts +111 -0
- package/Components/OfflineHandler/index.tsx +51 -73
- package/Components/OfflineHandler/utils/index.ts +1 -13
- package/Components/PlayerContainer/PlayerContainer.tsx +11 -7
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +66 -13
- package/Components/PreloaderWrapper/index.tsx +1 -1
- package/Components/River/ComponentsMap/ComponentsMap.tsx +85 -59
- package/Components/River/River.tsx +4 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +140 -75
- package/Components/River/__tests__/componentsMap.test.js +8 -3
- package/Components/River/__tests__/resultCallback.test.tsx +47 -0
- package/Components/Screen/__tests__/Screen.test.tsx +24 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/index.tsx +5 -0
- package/Components/Screen/navigationHandler.ts +8 -8
- package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +5 -3
- package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +1 -1
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
- package/Components/TopCutoffOverlay/index.tsx +2 -2
- package/Components/Transitioner/Transitioner.tsx +30 -20
- package/Components/Transitioner/__tests__/transitioner.test.js +83 -2
- package/Components/VideoLive/LiveImageManager.ts +9 -3
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
- package/Contexts/ModalNavigationContext/index.tsx +2 -2
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +6 -5
- package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +0 -112
- package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +0 -107
- package/Components/OfflineHandler/NotificationView/NotificationView.tsx +0 -153
- package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -66
- package/Components/OfflineHandler/NotificationView/utils.ts +0 -34
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Pressable } from "react-native";
|
|
3
|
+
import { fireEvent, render, screen } from "@testing-library/react-native";
|
|
4
|
+
import { getCell } from "../index";
|
|
5
|
+
import { standardCell } from "../standardCell";
|
|
6
|
+
import { selectableCell } from "../selectableCell";
|
|
7
|
+
import { dynamicCollectionCell } from "../dynamicCollectionCell";
|
|
8
|
+
import { mapMenuItemToPlaylistData } from "../../AudioPlayer/Components/Item";
|
|
9
|
+
|
|
10
|
+
describe("getCell", () => {
|
|
11
|
+
it("returns selectable cell for collection_selector", () => {
|
|
12
|
+
expect(getCell("collection_selector")).toBe(selectableCell);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("returns selectable cell for preference_editor", () => {
|
|
16
|
+
expect(getCell("preference_editor")).toBe(selectableCell);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("returns standard cell when role is undefined", () => {
|
|
20
|
+
expect(getCell(undefined)).toBe(standardCell);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("returns standard cell for unknown roles", () => {
|
|
24
|
+
expect(getCell("unknown_role")).toBe(standardCell);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("returns the dynamic collection cell for dynamic_collection", () => {
|
|
28
|
+
expect(getCell("dynamic_collection")).toBe(dynamicCollectionCell);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("does not use behavior to select the cell family", () => {
|
|
32
|
+
expect(getCell(undefined, { selectMode: "multi" })).toBe(standardCell);
|
|
33
|
+
|
|
34
|
+
expect(getCell("collection_selector", { selectMode: "single" })).toBe(
|
|
35
|
+
selectableCell
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe("mapMenuItemToPlaylistData", () => {
|
|
41
|
+
const item = {
|
|
42
|
+
title: "Playlist 1",
|
|
43
|
+
summary: "5 items",
|
|
44
|
+
icon: "https://example.com/icon.png",
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
it("defaults to multiSelect trailing button when selectMode is multi or undefined", () => {
|
|
48
|
+
const data1 = mapMenuItemToPlaylistData(item, { selectMode: "multi" });
|
|
49
|
+
expect(data1.trailingButton).toBe("multiSelect");
|
|
50
|
+
|
|
51
|
+
const data2 = mapMenuItemToPlaylistData(item);
|
|
52
|
+
expect(data2.trailingButton).toBe("multiSelect");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("omits trailing button when behavior selectMode is none", () => {
|
|
56
|
+
const data = mapMenuItemToPlaylistData(item, { selectMode: "none" });
|
|
57
|
+
expect(data.trailingButton).toBeUndefined();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it("omits trailing button when item trailingButton is explicitly none", () => {
|
|
61
|
+
const itemWithNone = { ...item, trailingButton: "none" };
|
|
62
|
+
|
|
63
|
+
const data = mapMenuItemToPlaylistData(itemWithNone, {
|
|
64
|
+
selectMode: "multi",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(data.trailingButton).toBeUndefined();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe("selectableCell checkbox press", () => {
|
|
72
|
+
it("invokes onPress with the playlist item when the checkbox is pressed", () => {
|
|
73
|
+
const onPress = jest.fn();
|
|
74
|
+
const item = { id: "queue", title: "Queue" };
|
|
75
|
+
|
|
76
|
+
render(
|
|
77
|
+
selectableCell.renderItem({
|
|
78
|
+
item,
|
|
79
|
+
index: 0,
|
|
80
|
+
onPress,
|
|
81
|
+
context: { behavior: { selectMode: "multi" } } as any,
|
|
82
|
+
}) as React.ReactElement
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const pressables = screen.UNSAFE_getAllByType(Pressable);
|
|
86
|
+
fireEvent.press(pressables[pressables.length - 1]);
|
|
87
|
+
|
|
88
|
+
expect(onPress).toHaveBeenCalledWith(item);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
AudioPlayerTrackItem,
|
|
4
|
+
VARIANT_QUEUED_ITEM,
|
|
5
|
+
ItemData,
|
|
6
|
+
} from "../AudioPlayer/Components/Item";
|
|
7
|
+
import type { CellRenderer, RenderItemArgs } from "./types";
|
|
8
|
+
import {
|
|
9
|
+
MenuItem,
|
|
10
|
+
OPERATIONS,
|
|
11
|
+
hasOperation,
|
|
12
|
+
} from "@applicaster/zapp-react-native-utils/modalState";
|
|
13
|
+
|
|
14
|
+
function mapMenuItemToDynamicData(
|
|
15
|
+
item: MenuItem,
|
|
16
|
+
operations: string[]
|
|
17
|
+
): ItemData {
|
|
18
|
+
const hasRemove = hasOperation(operations, OPERATIONS.REMOVE);
|
|
19
|
+
const hasReorder = hasOperation(operations, OPERATIONS.REORDER);
|
|
20
|
+
|
|
21
|
+
const title =
|
|
22
|
+
typeof item?.title === "string"
|
|
23
|
+
? item.title
|
|
24
|
+
: item?.title != null
|
|
25
|
+
? String(item.title)
|
|
26
|
+
: "";
|
|
27
|
+
|
|
28
|
+
const summary =
|
|
29
|
+
typeof item?.summary === "string"
|
|
30
|
+
? item.summary.trim()
|
|
31
|
+
: item?.summary != null
|
|
32
|
+
? String(item.summary)
|
|
33
|
+
: "";
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
imageUri: item?.icon,
|
|
37
|
+
textLabel1: title,
|
|
38
|
+
textLabel2: summary,
|
|
39
|
+
leadingButton: hasRemove ? "remove" : undefined,
|
|
40
|
+
trailingButton: hasReorder ? "drag" : undefined,
|
|
41
|
+
isSelected: item?.isSelected,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export const dynamicCollectionCell: CellRenderer = {
|
|
46
|
+
renderItem: ({
|
|
47
|
+
item,
|
|
48
|
+
index,
|
|
49
|
+
onPress,
|
|
50
|
+
context,
|
|
51
|
+
renderHandle,
|
|
52
|
+
}: RenderItemArgs) => {
|
|
53
|
+
const { editableCollection } = context;
|
|
54
|
+
const operations = editableCollection?.operations || [];
|
|
55
|
+
|
|
56
|
+
const handleRemove = () => {
|
|
57
|
+
if (editableCollection?.remove) {
|
|
58
|
+
editableCollection.remove(index);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const handleDrag = () => {
|
|
63
|
+
// Drag is managed by SortableList drag handle context
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<AudioPlayerTrackItem
|
|
68
|
+
key={item.id}
|
|
69
|
+
configuration={VARIANT_QUEUED_ITEM}
|
|
70
|
+
data={mapMenuItemToDynamicData(item, operations)}
|
|
71
|
+
onPress={() => onPress(item)}
|
|
72
|
+
onLeadingButtonPress={handleRemove}
|
|
73
|
+
onTrailingButtonPress={handleDrag}
|
|
74
|
+
renderHandle={renderHandle}
|
|
75
|
+
/>
|
|
76
|
+
);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SelectionBehavior } from "@applicaster/zapp-react-native-utils/modalState";
|
|
2
|
+
import { selectableCell } from "./selectableCell";
|
|
3
|
+
import { standardCell } from "./standardCell";
|
|
4
|
+
import type { CellRenderer } from "./types";
|
|
5
|
+
|
|
6
|
+
export type { CellRenderer, RenderItemArgs, SheetRenderContext } from "./types";
|
|
7
|
+
|
|
8
|
+
export { standardCell } from "./standardCell";
|
|
9
|
+
|
|
10
|
+
export { selectableCell } from "./selectableCell";
|
|
11
|
+
|
|
12
|
+
import { dynamicCollectionCell } from "./dynamicCollectionCell";
|
|
13
|
+
|
|
14
|
+
const SELECTION_ROLES = new Set(["collection_selector", "preference_editor"]);
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the row cell from feed role (+ behavior for future config only).
|
|
18
|
+
* Unknown / none -> standard Button cell.
|
|
19
|
+
*/
|
|
20
|
+
export const getCell = (
|
|
21
|
+
role?: string,
|
|
22
|
+
_behavior?: SelectionBehavior
|
|
23
|
+
): CellRenderer => {
|
|
24
|
+
if (role === "dynamic_collection") return dynamicCollectionCell;
|
|
25
|
+
|
|
26
|
+
return role && SELECTION_ROLES.has(role) ? selectableCell : standardCell;
|
|
27
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
AudioPlayerTrackItem,
|
|
4
|
+
mapMenuItemToPlaylistData,
|
|
5
|
+
VARIANT_PLAYLIST_ITEM,
|
|
6
|
+
} from "../AudioPlayer/Components/Item";
|
|
7
|
+
import type { CellRenderer } from "./types";
|
|
8
|
+
|
|
9
|
+
export const selectableCell: CellRenderer = {
|
|
10
|
+
renderItem: ({ item, onPress, context }) => (
|
|
11
|
+
<AudioPlayerTrackItem
|
|
12
|
+
key={item.id}
|
|
13
|
+
configuration={VARIANT_PLAYLIST_ITEM}
|
|
14
|
+
data={mapMenuItemToPlaylistData(item, context?.behavior)}
|
|
15
|
+
onPress={() => onPress(item)}
|
|
16
|
+
onTrailingButtonPress={
|
|
17
|
+
item.secondaryAction?.action
|
|
18
|
+
? () =>
|
|
19
|
+
onPress({
|
|
20
|
+
id: `${item.id}_secondary`,
|
|
21
|
+
title: item.title,
|
|
22
|
+
action: item.secondaryAction!.action,
|
|
23
|
+
})
|
|
24
|
+
: () => onPress(item)
|
|
25
|
+
}
|
|
26
|
+
/>
|
|
27
|
+
),
|
|
28
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { CellRenderer } from "./types";
|
|
3
|
+
|
|
4
|
+
export const standardCell: CellRenderer = {
|
|
5
|
+
renderItem: ({ item, onPress, context }) => {
|
|
6
|
+
if (!item) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const {
|
|
11
|
+
theme,
|
|
12
|
+
ButtonComponent,
|
|
13
|
+
current_selection,
|
|
14
|
+
iconBaseProps,
|
|
15
|
+
itemBaseProps,
|
|
16
|
+
labelBaseProps,
|
|
17
|
+
getSelectedItemIcon,
|
|
18
|
+
getDefaultItemIcon,
|
|
19
|
+
iconPlacement,
|
|
20
|
+
} = context;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<ButtonComponent
|
|
24
|
+
key={item.id}
|
|
25
|
+
configuration={theme}
|
|
26
|
+
selectedItem={current_selection}
|
|
27
|
+
item={item}
|
|
28
|
+
onPress={onPress}
|
|
29
|
+
label={
|
|
30
|
+
theme[(item as any)?.label] ?? ((item as any)?.label || item?.title)
|
|
31
|
+
}
|
|
32
|
+
iconBaseProps={iconBaseProps}
|
|
33
|
+
itemBaseProps={itemBaseProps}
|
|
34
|
+
labelBaseProps={labelBaseProps}
|
|
35
|
+
selectedItemIcon={getSelectedItemIcon(theme)}
|
|
36
|
+
defaultItemIcon={getDefaultItemIcon(theme)}
|
|
37
|
+
iconPlacement={iconPlacement}
|
|
38
|
+
/>
|
|
39
|
+
);
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type {
|
|
3
|
+
MenuItem,
|
|
4
|
+
SelectionBehavior,
|
|
5
|
+
} from "@applicaster/zapp-react-native-utils/modalState";
|
|
6
|
+
import type { EditableCollection } from "@applicaster/zapp-react-native-utils/modalState/EditableCollection";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Extra props row renderers need.
|
|
10
|
+
*/
|
|
11
|
+
export type SheetRenderContext = {
|
|
12
|
+
theme: any;
|
|
13
|
+
ButtonComponent: React.ComponentType<any>;
|
|
14
|
+
current_selection?: any;
|
|
15
|
+
iconBaseProps: any;
|
|
16
|
+
itemBaseProps: any;
|
|
17
|
+
labelBaseProps: any;
|
|
18
|
+
getSelectedItemIcon: (theme: any) => any;
|
|
19
|
+
getDefaultItemIcon: (theme: any) => any;
|
|
20
|
+
iconPlacement?: "left" | "right";
|
|
21
|
+
editableCollection?: EditableCollection | null;
|
|
22
|
+
behavior?: SelectionBehavior;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type RenderItemArgs = {
|
|
26
|
+
item: MenuItem;
|
|
27
|
+
index: number;
|
|
28
|
+
onPress: (item: MenuItem) => void;
|
|
29
|
+
context: SheetRenderContext;
|
|
30
|
+
renderHandle?: (children: React.ReactElement) => React.ReactElement;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type CellRenderer = {
|
|
34
|
+
renderItem: (args: RenderItemArgs) => React.ReactNode;
|
|
35
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
actionExecutor,
|
|
3
|
+
ActionResult,
|
|
4
|
+
} from "@applicaster/zapp-react-native-utils/actionsExecutor/ActionExecutor";
|
|
5
|
+
import { TextInputContent } from "./TextInputContent";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Opens a text-input bottom sheet driven by action.options.
|
|
9
|
+
* Uses openBottomSheet with content.component as body-only UI;
|
|
10
|
+
* standard ModalHeader (dismiss x) is provided by ModalComponent.
|
|
11
|
+
*/
|
|
12
|
+
export async function showTextInputAction(
|
|
13
|
+
action: ActionType,
|
|
14
|
+
context?: Record<string, any>
|
|
15
|
+
): Promise<ActionResult> {
|
|
16
|
+
const {
|
|
17
|
+
headerTitle,
|
|
18
|
+
inputLabel,
|
|
19
|
+
defaultValue,
|
|
20
|
+
buttonLabel,
|
|
21
|
+
validationLabel,
|
|
22
|
+
actions,
|
|
23
|
+
maxLength,
|
|
24
|
+
} = action.options || {};
|
|
25
|
+
|
|
26
|
+
if (!headerTitle || !buttonLabel || !actions || !actions.length) {
|
|
27
|
+
return ActionResult.Error;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return actionExecutor.handleAction(
|
|
31
|
+
{
|
|
32
|
+
type: "openBottomSheet",
|
|
33
|
+
options: {
|
|
34
|
+
header: {
|
|
35
|
+
title: headerTitle,
|
|
36
|
+
},
|
|
37
|
+
content: {
|
|
38
|
+
component: TextInputContent,
|
|
39
|
+
props: {
|
|
40
|
+
maxLength,
|
|
41
|
+
inputLabel,
|
|
42
|
+
defaultValue: defaultValue ?? "",
|
|
43
|
+
buttonLabel,
|
|
44
|
+
actions,
|
|
45
|
+
validationLabel,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
context
|
|
51
|
+
);
|
|
52
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
2
|
+
import {
|
|
3
|
+
toNumberWithDefault,
|
|
4
|
+
toNumberWithDefaultZero,
|
|
5
|
+
} from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
2
6
|
import { PluginConfiguration } from "./";
|
|
3
7
|
import { ItemIconProps } from "./Button/ItemIcon";
|
|
4
8
|
import { ItemLabelProps } from "./Button/ItemLabel";
|
|
@@ -6,7 +10,8 @@ import { ItemProps } from "./Button/Item";
|
|
|
6
10
|
|
|
7
11
|
export function defaultItemProps(
|
|
8
12
|
config: PluginConfiguration,
|
|
9
|
-
maxWidth: number
|
|
13
|
+
maxWidth: number,
|
|
14
|
+
blockItemStyle?: Record<string, any>
|
|
10
15
|
): ItemProps {
|
|
11
16
|
const {
|
|
12
17
|
modal_bottom_sheet_item_background_color,
|
|
@@ -24,19 +29,36 @@ export function defaultItemProps(
|
|
|
24
29
|
modal_bottom_sheet_item_padding_top,
|
|
25
30
|
} = config;
|
|
26
31
|
|
|
32
|
+
const bgDefault = blockItemStyle?.background?.default;
|
|
33
|
+
|
|
34
|
+
const bgFocused =
|
|
35
|
+
blockItemStyle?.background?.focused || blockItemStyle?.background?.focus;
|
|
36
|
+
|
|
27
37
|
return {
|
|
28
|
-
backgroundColor:
|
|
29
|
-
|
|
38
|
+
backgroundColor:
|
|
39
|
+
bgDefault?.backgroundColor || modal_bottom_sheet_item_background_color,
|
|
40
|
+
focusedBackgroundColor:
|
|
41
|
+
bgFocused?.backgroundColor ||
|
|
42
|
+
modal_bottom_sheet_item_focus_background_color,
|
|
30
43
|
selectedBackgroundColor: modal_bottom_sheet_item_selected_background_color,
|
|
31
44
|
focusedSelectedBackgroundColor:
|
|
32
45
|
modal_bottom_sheet_item_focused_selected_background_color,
|
|
33
|
-
borderRadius:
|
|
46
|
+
borderRadius: toNumberWithDefault(
|
|
47
|
+
modal_bottom_sheet_item_corner_radius,
|
|
48
|
+
bgDefault?.borderRadius
|
|
49
|
+
),
|
|
34
50
|
marginBottom: modal_bottom_sheet_item_margin_bottom,
|
|
35
51
|
marginTop: modal_bottom_sheet_item_margin_top,
|
|
36
52
|
marginLeft: modal_bottom_sheet_item_margin_left,
|
|
37
53
|
marginRight: modal_bottom_sheet_item_margin_right,
|
|
38
|
-
paddingTop:
|
|
39
|
-
|
|
54
|
+
paddingTop: toNumberWithDefault(
|
|
55
|
+
modal_bottom_sheet_item_padding_top,
|
|
56
|
+
bgDefault?.paddingTop
|
|
57
|
+
),
|
|
58
|
+
paddingBottom: toNumberWithDefault(
|
|
59
|
+
modal_bottom_sheet_item_padding_bottom,
|
|
60
|
+
bgDefault?.paddingBottom
|
|
61
|
+
),
|
|
40
62
|
paddingRight: modal_bottom_sheet_item_padding_right,
|
|
41
63
|
paddingLeft: modal_bottom_sheet_item_padding_left,
|
|
42
64
|
maxWidth,
|
|
@@ -45,7 +67,8 @@ export function defaultItemProps(
|
|
|
45
67
|
|
|
46
68
|
export function defaultItemLabelProps(
|
|
47
69
|
config: PluginConfiguration,
|
|
48
|
-
sheetWidth: number
|
|
70
|
+
sheetWidth: number,
|
|
71
|
+
blockItemStyle?: Record<string, any>
|
|
49
72
|
): ItemLabelProps {
|
|
50
73
|
const {
|
|
51
74
|
modal_bottom_sheet_item_label_android_letter_spacing,
|
|
@@ -72,15 +95,48 @@ export function defaultItemLabelProps(
|
|
|
72
95
|
modal_bottom_sheet_item_padding_right,
|
|
73
96
|
} = config;
|
|
74
97
|
|
|
75
|
-
const
|
|
98
|
+
const iconWidth = toNumberWithDefaultZero(modal_bottom_sheet_item_icon_width);
|
|
99
|
+
|
|
100
|
+
const iconMarginLeft = toNumberWithDefaultZero(
|
|
101
|
+
modal_bottom_sheet_item_icon_margin_left
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const iconMarginRight = toNumberWithDefaultZero(
|
|
105
|
+
modal_bottom_sheet_item_icon_margin_right
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const itemMarginLeft = toNumberWithDefaultZero(
|
|
109
|
+
modal_bottom_sheet_item_margin_left
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const itemMarginRight = toNumberWithDefaultZero(
|
|
113
|
+
modal_bottom_sheet_item_margin_right
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const itemPaddingLeft = toNumberWithDefaultZero(
|
|
117
|
+
modal_bottom_sheet_item_padding_left
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const itemPaddingRight = toNumberWithDefaultZero(
|
|
121
|
+
modal_bottom_sheet_item_padding_right
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const calculatedMaxWidth =
|
|
76
125
|
sheetWidth -
|
|
77
|
-
(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
126
|
+
(iconWidth +
|
|
127
|
+
iconMarginLeft +
|
|
128
|
+
iconMarginRight +
|
|
129
|
+
itemMarginLeft +
|
|
130
|
+
itemMarginRight +
|
|
131
|
+
itemPaddingLeft +
|
|
132
|
+
itemPaddingRight);
|
|
133
|
+
|
|
134
|
+
const maxWidth =
|
|
135
|
+
Number.isNaN(calculatedMaxWidth) || calculatedMaxWidth <= 0
|
|
136
|
+
? sheetWidth
|
|
137
|
+
: calculatedMaxWidth;
|
|
138
|
+
|
|
139
|
+
const label1Default = blockItemStyle?.textLabel1?.default;
|
|
84
140
|
|
|
85
141
|
return {
|
|
86
142
|
fontFamily: platformSelect({
|
|
@@ -91,8 +147,11 @@ export function defaultItemLabelProps(
|
|
|
91
147
|
ios: modal_bottom_sheet_item_label_ios_letter_spacing,
|
|
92
148
|
android: modal_bottom_sheet_item_label_android_letter_spacing,
|
|
93
149
|
}),
|
|
94
|
-
fontSize:
|
|
95
|
-
|
|
150
|
+
fontSize: toNumberWithDefault(
|
|
151
|
+
modal_bottom_sheet_item_label_font_size,
|
|
152
|
+
label1Default?.fontSize
|
|
153
|
+
),
|
|
154
|
+
color: label1Default?.fontColor || modal_bottom_sheet_item_label_font_color,
|
|
96
155
|
focusColor: modal_bottom_sheet_item_label_focus_font_color,
|
|
97
156
|
hoverSelectedColor: modal_bottom_sheet_item_label_hover_selected_font_color,
|
|
98
157
|
selectedColor: modal_bottom_sheet_item_label_selected_font_color,
|
|
@@ -146,7 +205,8 @@ export function getItemLabelProps(
|
|
|
146
205
|
width: number,
|
|
147
206
|
labelProps?:
|
|
148
207
|
| ((theme: PluginConfiguration, width: number) => ItemLabelProps)
|
|
149
|
-
| ItemLabelProps
|
|
208
|
+
| ItemLabelProps,
|
|
209
|
+
blockItemStyle?: Record<string, any>
|
|
150
210
|
) {
|
|
151
211
|
if (labelProps) {
|
|
152
212
|
return typeof labelProps === "function"
|
|
@@ -154,7 +214,7 @@ export function getItemLabelProps(
|
|
|
154
214
|
: labelProps;
|
|
155
215
|
}
|
|
156
216
|
|
|
157
|
-
return defaultItemLabelProps(theme, width);
|
|
217
|
+
return defaultItemLabelProps(theme, width, blockItemStyle);
|
|
158
218
|
}
|
|
159
219
|
|
|
160
220
|
export function getItemProps(
|
|
@@ -162,7 +222,8 @@ export function getItemProps(
|
|
|
162
222
|
width: number,
|
|
163
223
|
itemProps?:
|
|
164
224
|
| ((theme: PluginConfiguration, width: number) => ItemProps)
|
|
165
|
-
| ItemProps
|
|
225
|
+
| ItemProps,
|
|
226
|
+
blockItemStyle?: Record<string, any>
|
|
166
227
|
) {
|
|
167
228
|
if (itemProps) {
|
|
168
229
|
return typeof itemProps === "function"
|
|
@@ -170,5 +231,5 @@ export function getItemProps(
|
|
|
170
231
|
: itemProps;
|
|
171
232
|
}
|
|
172
233
|
|
|
173
|
-
return defaultItemProps(theme, width);
|
|
234
|
+
return defaultItemProps(theme, width, blockItemStyle);
|
|
174
235
|
}
|
|
@@ -1,88 +1,7 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
|
-
exports[`OfflineHandler renders 1`] = `
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
"flex": 1,
|
|
8
|
-
"position": "relative",
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
>
|
|
12
|
-
<View
|
|
13
|
-
style={
|
|
14
|
-
{
|
|
15
|
-
"bottom": 0,
|
|
16
|
-
"left": 0,
|
|
17
|
-
"position": "absolute",
|
|
18
|
-
"right": 0,
|
|
19
|
-
"top": 0,
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
>
|
|
23
|
-
<View
|
|
24
|
-
accessibilityState={
|
|
25
|
-
{
|
|
26
|
-
"busy": undefined,
|
|
27
|
-
"checked": undefined,
|
|
28
|
-
"disabled": undefined,
|
|
29
|
-
"expanded": undefined,
|
|
30
|
-
"selected": undefined,
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
accessible={true}
|
|
34
|
-
collapsable={false}
|
|
35
|
-
focusable={true}
|
|
36
|
-
onClick={[Function]}
|
|
37
|
-
onResponderGrant={[Function]}
|
|
38
|
-
onResponderMove={[Function]}
|
|
39
|
-
onResponderRelease={[Function]}
|
|
40
|
-
onResponderTerminate={[Function]}
|
|
41
|
-
onResponderTerminationRequest={[Function]}
|
|
42
|
-
onStartShouldSetResponder={[Function]}
|
|
43
|
-
style={
|
|
44
|
-
{
|
|
45
|
-
"alignItems": "center",
|
|
46
|
-
"backgroundColor": undefined,
|
|
47
|
-
"flex": 1,
|
|
48
|
-
"height": 88,
|
|
49
|
-
"justifyContent": "center",
|
|
50
|
-
"left": 0,
|
|
51
|
-
"opacity": 0,
|
|
52
|
-
"position": "absolute",
|
|
53
|
-
"right": 0,
|
|
54
|
-
"top": 0,
|
|
55
|
-
"transform": [
|
|
56
|
-
{
|
|
57
|
-
"translateY": -88,
|
|
58
|
-
},
|
|
59
|
-
],
|
|
60
|
-
"width": "100%",
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
>
|
|
64
|
-
<View
|
|
65
|
-
style={
|
|
66
|
-
{
|
|
67
|
-
"backgroundColor": undefined,
|
|
68
|
-
"height": 44,
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/>
|
|
72
|
-
<Text
|
|
73
|
-
style={
|
|
74
|
-
{
|
|
75
|
-
"color": undefined,
|
|
76
|
-
"fontFamily": undefined,
|
|
77
|
-
"fontSize": undefined,
|
|
78
|
-
"letterSpacing": undefined,
|
|
79
|
-
"lineHeight": undefined,
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
>
|
|
83
|
-
You are back online
|
|
84
|
-
</Text>
|
|
85
|
-
</View>
|
|
86
|
-
</View>
|
|
87
|
-
</View>
|
|
3
|
+
exports[`OfflineHandler renders its children without wrapping them in a notification view 1`] = `
|
|
4
|
+
<Text>
|
|
5
|
+
child content
|
|
6
|
+
</Text>
|
|
88
7
|
`;
|