@applicaster/zapp-react-native-ui-components 16.0.0-rc.64 → 16.0.0-rc.66
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.
|
@@ -16,10 +16,19 @@ type Props = {
|
|
|
16
16
|
export const Toggle = (props: Props) => {
|
|
17
17
|
const { style, item, action, cellState } = props;
|
|
18
18
|
|
|
19
|
-
const {
|
|
19
|
+
const {
|
|
20
|
+
trackColor,
|
|
21
|
+
trackColorActive,
|
|
22
|
+
thumbColor,
|
|
23
|
+
thumbColorActive,
|
|
24
|
+
iosBackgroundColor,
|
|
25
|
+
} = style;
|
|
20
26
|
|
|
27
|
+
// `focused_selected` is the selected state with a finger on the row, so the
|
|
28
|
+
// switch has to read as on for both. Leaving it out reads a pressed selected
|
|
29
|
+
// row as off, which flips the thumb for the duration of the press.
|
|
21
30
|
const isSelected = React.useMemo(
|
|
22
|
-
() => cellState === "selected",
|
|
31
|
+
() => cellState === "selected" || cellState === "focused_selected",
|
|
23
32
|
[item?.id, cellState]
|
|
24
33
|
);
|
|
25
34
|
|
|
@@ -30,13 +39,16 @@ export const Toggle = (props: Props) => {
|
|
|
30
39
|
// selection state and writes through the entry's tap actions, the same path a
|
|
31
40
|
// tap on the row takes.
|
|
32
41
|
//
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
42
|
+
// An empty identifier is the way to ask for that, which is why the cell
|
|
43
|
+
// manifest declares no initial_value for `toggle_action_identifier`:
|
|
44
|
+
// `castOrDefault` substitutes the default whenever the configured value is
|
|
45
|
+
// empty - and an empty string counts as empty - so any default there would be
|
|
46
|
+
// uncleanable and would force every toggle onto that plugin.
|
|
47
|
+
//
|
|
48
|
+
// The route is still decided on whether the identifier resolves to an
|
|
49
|
+
// installed action plugin rather than on the string being non-empty. App
|
|
50
|
+
// configurations saved while the old default was in the manifest still carry
|
|
51
|
+
// it, and a mistyped plugin id has to fall back the same way.
|
|
40
52
|
const hasActionPlugin = Boolean(
|
|
41
53
|
action?.identifier && actionContext?.invokeAction
|
|
42
54
|
);
|
|
@@ -61,6 +73,7 @@ export const Toggle = (props: Props) => {
|
|
|
61
73
|
<Switch
|
|
62
74
|
trackColor={{ false: trackColor, true: trackColorActive }}
|
|
63
75
|
thumbColor={isSelected ? thumbColorActive : thumbColor}
|
|
76
|
+
ios_backgroundColor={iosBackgroundColor}
|
|
64
77
|
onValueChange={onPress}
|
|
65
78
|
value={isSelected}
|
|
66
79
|
/>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { fireEvent, render } from "@testing-library/react-native";
|
|
3
|
+
import { Switch } from "react-native";
|
|
3
4
|
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
4
5
|
|
|
5
6
|
import { Toggle } from "../Toggle";
|
|
@@ -56,6 +57,21 @@ describe("Toggle with an empty action identifier", () => {
|
|
|
56
57
|
expect(getByRole("switch").props.value).toBe(false);
|
|
57
58
|
});
|
|
58
59
|
|
|
60
|
+
// A finger on a selected row resolves the cell to focused_selected. Reading
|
|
61
|
+
// that as unselected flipped the thumb for the duration of the press and let
|
|
62
|
+
// it jump back on release, which reads as a second tap.
|
|
63
|
+
it("stays on while a selected cell is pressed", () => {
|
|
64
|
+
const { getByRole } = renderToggle("", "focused_selected");
|
|
65
|
+
|
|
66
|
+
expect(getByRole("switch").props.value).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("is off while an unselected cell is pressed", () => {
|
|
70
|
+
const { getByRole } = renderToggle("", "focused");
|
|
71
|
+
|
|
72
|
+
expect(getByRole("switch").props.value).toBe(false);
|
|
73
|
+
});
|
|
74
|
+
|
|
59
75
|
it("routes a change through the cell click path", () => {
|
|
60
76
|
const { getByRole } = renderToggle("", "default");
|
|
61
77
|
|
|
@@ -70,6 +86,23 @@ describe("Toggle with an empty action identifier", () => {
|
|
|
70
86
|
|
|
71
87
|
expect(mockInitialEntryState).not.toHaveBeenCalled();
|
|
72
88
|
});
|
|
89
|
+
|
|
90
|
+
// ios_backgroundColor paints behind the track, so trackColor does not cover
|
|
91
|
+
// it and it has to be forwarded on its own. It was dropped once while the
|
|
92
|
+
// destructure feeding it was being reformatted, and nothing caught that.
|
|
93
|
+
//
|
|
94
|
+
// Asserted on the Switch element rather than the rendered host component:
|
|
95
|
+
// what Toggle owns is the props it hands to Switch, and React Native rewrites
|
|
96
|
+
// them into platform-specific ones (tintColor, a style entry) underneath.
|
|
97
|
+
it("forwards every configured color to the switch", () => {
|
|
98
|
+
const { UNSAFE_getByType } = renderToggle("", "default");
|
|
99
|
+
|
|
100
|
+
expect(UNSAFE_getByType(Switch).props).toMatchObject({
|
|
101
|
+
trackColor: { false: style.trackColor, true: style.trackColorActive },
|
|
102
|
+
thumbColor: style.thumbColor,
|
|
103
|
+
ios_backgroundColor: style.iosBackgroundColor,
|
|
104
|
+
});
|
|
105
|
+
});
|
|
73
106
|
});
|
|
74
107
|
|
|
75
108
|
describe("Toggle with an action plugin identifier", () => {
|
|
@@ -92,11 +125,11 @@ describe("Toggle with an action plugin identifier", () => {
|
|
|
92
125
|
});
|
|
93
126
|
|
|
94
127
|
describe("Toggle with an identifier whose action plugin is not installed", () => {
|
|
95
|
-
// The cell manifest
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// non-empty identifier it never asked for - the presence of a real
|
|
99
|
-
// context, not the identifier string, is what decides the route.
|
|
128
|
+
// The cell manifest no longer defaults toggle_action_identifier, but app
|
|
129
|
+
// configurations saved while it did still carry "firebase-push-topic-action",
|
|
130
|
+
// and a mistyped id is always possible. A toggle can therefore still arrive
|
|
131
|
+
// with a non-empty identifier it never asked for - the presence of a real
|
|
132
|
+
// action context, not the identifier string, is what decides the route.
|
|
100
133
|
beforeEach(() => {
|
|
101
134
|
jest.clearAllMocks();
|
|
102
135
|
|
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.66",
|
|
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.66",
|
|
32
|
+
"@applicaster/zapp-react-native-bridge": "16.0.0-rc.66",
|
|
33
|
+
"@applicaster/zapp-react-native-redux": "16.0.0-rc.66",
|
|
34
|
+
"@applicaster/zapp-react-native-utils": "16.0.0-rc.66",
|
|
35
35
|
"fast-json-stable-stringify": "^2.1.0",
|
|
36
36
|
"promise": "^8.3.0",
|
|
37
37
|
"react-native-sortables": "1.7.1",
|