@shopify/app-bridge-react 2.0.25 → 2.0.26
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/CHANGELOG.md +15 -0
- package/components/Modal/Modal.d.ts +3 -14
- package/components/Modal/Modal.js +101 -94
- package/components/NavigationMenu/NavigationMenu.js +29 -44
- package/components/TitleBar/TitleBar.js +70 -17
- package/package.json +3 -3
- package/umd/index.js +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.26](https://github.com/Shopify/app-bridge/compare/v2.0.25...v2.0.26) (2022-04-28)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **app-bridge:** creating a title bar with empty options should not dispatch an update action ([c31f135](https://github.com/Shopify/app-bridge/commit/c31f135ffb78b3c69278cef0ce0674eb55aa7837))
|
|
12
|
+
* **app-bridge-react:** ensure Modal component only dispatch UPDATE action when necessary ([3f6bd1a](https://github.com/Shopify/app-bridge/commit/3f6bd1ae4c7475b2cccad646e0e4b5c17f681693))
|
|
13
|
+
* **app-bridge-react:** stop sending unnecessary updates when Navigation Menu props have not changed ([5d57495](https://github.com/Shopify/app-bridge/commit/5d57495bda42b37913f1c582159f04aab97d478a))
|
|
14
|
+
* **app-bridge-react:** update redirect callbacks for title bar when onAction changes ([68cd7ac](https://github.com/Shopify/app-bridge/commit/68cd7ace44b3cf92c4adb76e3d975e7a63b61b59))
|
|
15
|
+
* **app-bridge-react:** update title bar callbacks when they change ([617f900](https://github.com/Shopify/app-bridge/commit/617f900a6c4c8826e931ab20a6cb892e1ada98cf))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
6
21
|
## [2.0.25](https://github.com/Shopify/app-bridge/compare/v2.0.24...v2.0.25) (2022-04-20)
|
|
7
22
|
|
|
8
23
|
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Modal as AppBridgeModal } from '@shopify/app-bridge/actions';
|
|
1
|
+
import { Size } from '@shopify/app-bridge/actions/Modal';
|
|
3
2
|
import { ActionProps } from '../../types';
|
|
4
|
-
declare type Size = keyof typeof AppBridgeModal.Size;
|
|
5
3
|
export interface Props {
|
|
6
4
|
/** Whether the modal is open or not */
|
|
7
5
|
open: boolean;
|
|
@@ -10,7 +8,7 @@ export interface Props {
|
|
|
10
8
|
/** The content for the title of the modal */
|
|
11
9
|
title?: string;
|
|
12
10
|
/** Controls the size of the modal */
|
|
13
|
-
size?: Size;
|
|
11
|
+
size?: keyof typeof Size;
|
|
14
12
|
/** Message to display inside modal */
|
|
15
13
|
message?: string;
|
|
16
14
|
/** Primary action */
|
|
@@ -30,14 +28,5 @@ export interface Props {
|
|
|
30
28
|
*
|
|
31
29
|
* @public
|
|
32
30
|
*/
|
|
33
|
-
declare
|
|
34
|
-
static contextType: React.Context<import("../../context").IAppBridgeContext>;
|
|
35
|
-
private focusReturnPoint;
|
|
36
|
-
private modal;
|
|
37
|
-
componentDidMount(): void;
|
|
38
|
-
componentDidUpdate(prevProps: Props): void;
|
|
39
|
-
componentWillUnmount(): void;
|
|
40
|
-
render(): null;
|
|
41
|
-
private transformProps;
|
|
42
|
-
}
|
|
31
|
+
declare function Modal(props: Props): null;
|
|
43
32
|
export default Modal;
|
|
@@ -1,19 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
2
|
var __assign = (this && this.__assign) || function () {
|
|
18
3
|
__assign = Object.assign || function(t) {
|
|
19
4
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
@@ -25,14 +10,22 @@ var __assign = (this && this.__assign) || function () {
|
|
|
25
10
|
};
|
|
26
11
|
return __assign.apply(this, arguments);
|
|
27
12
|
};
|
|
28
|
-
var
|
|
29
|
-
|
|
13
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
14
|
+
var t = {};
|
|
15
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
16
|
+
t[p] = s[p];
|
|
17
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
18
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
19
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
20
|
+
t[p[i]] = s[p[i]];
|
|
21
|
+
}
|
|
22
|
+
return t;
|
|
30
23
|
};
|
|
31
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
-
var react_1 =
|
|
33
|
-
var
|
|
25
|
+
var react_1 = require("react");
|
|
26
|
+
var Modal_1 = require("@shopify/app-bridge/actions/Modal");
|
|
34
27
|
var transformers_1 = require("../../utilities/transformers");
|
|
35
|
-
var
|
|
28
|
+
var useAppBridge_1 = require("../../useAppBridge");
|
|
36
29
|
/**
|
|
37
30
|
* Modal component
|
|
38
31
|
*
|
|
@@ -41,92 +34,106 @@ var context_1 = require("../../context");
|
|
|
41
34
|
*
|
|
42
35
|
* @public
|
|
43
36
|
*/
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
37
|
+
function Modal(props) {
|
|
38
|
+
var app = useAppBridge_1.useAppBridge();
|
|
39
|
+
var focusReturnPoint = react_1.useRef(null);
|
|
40
|
+
// Initialize with open: false so the open action will dispatch on initial load
|
|
41
|
+
var prevProps = react_1.useRef({ open: false });
|
|
42
|
+
var open = props.open;
|
|
43
|
+
var isUnmounted = react_1.useRef(false);
|
|
44
|
+
var modal = react_1.useMemo(function () {
|
|
45
|
+
/**
|
|
46
|
+
* We purposely don't pass buttons here as they will be replaced
|
|
47
|
+
* by the subsequent useEffect to call `set` to update the options.
|
|
48
|
+
* If we pass them in here button subscriptions will be created without
|
|
49
|
+
* being cleaned up.
|
|
50
|
+
*/
|
|
51
|
+
var primaryAction = props.primaryAction, secondaryActions = props.secondaryActions, rest = __rest(props, ["primaryAction", "secondaryActions"]);
|
|
52
|
+
return Modal_1.create(app, transformProps(app, rest));
|
|
53
|
+
}, [app]);
|
|
54
|
+
/**
|
|
55
|
+
* All option updates are handled in this useEffect to avoid race conditions.
|
|
56
|
+
* For example, we need to call `modal.unsubscribe` to clean up button subscriptions
|
|
57
|
+
* but we calling it will also unsubscribe the onClose handler. Therefore we want
|
|
58
|
+
* to ensure all callbacks are handled in a single useEffect with a single clean up
|
|
59
|
+
* call to unsubscribe.
|
|
60
|
+
*/
|
|
61
|
+
react_1.useEffect(function () {
|
|
62
|
+
if (isUnmounted.current) {
|
|
63
|
+
prevProps.current = props;
|
|
64
|
+
return;
|
|
57
65
|
}
|
|
66
|
+
var wasOpen = prevProps.current.open;
|
|
67
|
+
var openUpdated = wasOpen !== open;
|
|
68
|
+
/** We only call `set` to update the options if the modal is open.
|
|
69
|
+
* This is because while the modal is closed updates don't take effect on screen.
|
|
70
|
+
*/
|
|
58
71
|
if (open) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.modal.unsubscribe();
|
|
68
|
-
if (isIframeModal(transformedProps)) {
|
|
69
|
-
this.modal.set(transformedProps, open);
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
this.modal.set(transformedProps, open);
|
|
73
|
-
}
|
|
74
|
-
if (onClose != null) {
|
|
75
|
-
this.modal.subscribe(actions_1.Modal.Action.CLOSE, onClose);
|
|
76
|
-
}
|
|
77
|
-
if (wasOpen !== open) {
|
|
78
|
-
if (open) {
|
|
79
|
-
this.modal.dispatch(actions_1.Modal.Action.OPEN);
|
|
72
|
+
var transformedProps = transformProps(app, props, wasOpen);
|
|
73
|
+
/** We skip dispatching the update action if we're about to update the open state.
|
|
74
|
+
* This is because the OPEN action will always sends the updated options
|
|
75
|
+
* so we don't need to send it twice.
|
|
76
|
+
*/
|
|
77
|
+
var shouldSendUpdate = !openUpdated;
|
|
78
|
+
if (isIframeModal(transformedProps)) {
|
|
79
|
+
modal.set(transformedProps, shouldSendUpdate);
|
|
80
80
|
}
|
|
81
81
|
else {
|
|
82
|
-
|
|
82
|
+
modal.set(transformedProps, shouldSendUpdate);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
!open &&
|
|
90
|
-
this.focusReturnPoint != null &&
|
|
91
|
-
document.contains(this.focusReturnPoint)) {
|
|
92
|
-
this.focusReturnPoint.focus();
|
|
93
|
-
this.focusReturnPoint = null;
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
Modal.prototype.componentWillUnmount = function () {
|
|
97
|
-
this.modal.unsubscribe();
|
|
98
|
-
if (this.props.open) {
|
|
99
|
-
this.modal.dispatch(actions_1.Modal.Action.CLOSE);
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
Modal.prototype.render = function () {
|
|
103
|
-
return null;
|
|
104
|
-
};
|
|
105
|
-
Modal.prototype.transformProps = function (wasOpen) {
|
|
106
|
-
var _a = this.props, title = _a.title, size = _a.size, message = _a.message, src = _a.src, primaryAction = _a.primaryAction, secondaryActions = _a.secondaryActions, loading = _a.loading;
|
|
107
|
-
var app = this.context;
|
|
108
|
-
var safeSize = size == null ? undefined : actions_1.Modal.Size[size];
|
|
109
|
-
var srcPayload = {};
|
|
110
|
-
if (src != null) {
|
|
111
|
-
if (src.match('^https?://')) {
|
|
112
|
-
srcPayload.url = src;
|
|
85
|
+
if (openUpdated) {
|
|
86
|
+
if (open) {
|
|
87
|
+
modal.dispatch(Modal_1.Action.OPEN);
|
|
88
|
+
focusReturnPoint.current = document.activeElement;
|
|
113
89
|
}
|
|
114
90
|
else {
|
|
115
|
-
|
|
91
|
+
modal.dispatch(Modal_1.Action.CLOSE);
|
|
92
|
+
if (focusReturnPoint.current != null && document.contains(focusReturnPoint.current)) {
|
|
93
|
+
focusReturnPoint.current.focus();
|
|
94
|
+
focusReturnPoint.current = null;
|
|
95
|
+
}
|
|
116
96
|
}
|
|
117
97
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
98
|
+
if (props.onClose != null) {
|
|
99
|
+
modal.subscribe(Modal_1.Action.CLOSE, props.onClose);
|
|
100
|
+
}
|
|
101
|
+
prevProps.current = props;
|
|
102
|
+
return function () {
|
|
103
|
+
// This is important to clean up previous buttons and onClose subscriptions
|
|
104
|
+
modal.unsubscribe();
|
|
105
|
+
};
|
|
106
|
+
}, [props, open]);
|
|
107
|
+
react_1.useEffect(function () {
|
|
108
|
+
return function () {
|
|
109
|
+
if (prevProps.current.open) {
|
|
110
|
+
modal.dispatch(Modal_1.Action.CLOSE);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}, [modal]);
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
128
116
|
function isIframeModal(options) {
|
|
129
117
|
return (typeof options.url === 'string' ||
|
|
130
118
|
typeof options.path === 'string');
|
|
131
119
|
}
|
|
120
|
+
function transformProps(app, props, wasOpen) {
|
|
121
|
+
var title = props.title, size = props.size, message = props.message, src = props.src, primaryAction = props.primaryAction, secondaryActions = props.secondaryActions, loading = props.loading;
|
|
122
|
+
var safeSize = size == null ? undefined : Modal_1.Size[size];
|
|
123
|
+
var srcPayload = {};
|
|
124
|
+
if (src != null) {
|
|
125
|
+
if (src.match('^https?://')) {
|
|
126
|
+
srcPayload.url = src;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
srcPayload.path = src;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return __assign(__assign({ title: title, message: message, size: safeSize }, srcPayload), { footer: {
|
|
133
|
+
buttons: transformers_1.transformActions(app, {
|
|
134
|
+
primaryAction: primaryAction,
|
|
135
|
+
secondaryActions: secondaryActions,
|
|
136
|
+
}),
|
|
137
|
+
}, loading: wasOpen ? undefined : loading });
|
|
138
|
+
}
|
|
132
139
|
exports.default = Modal;
|
|
@@ -1,55 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
3
|
var react_1 = require("react");
|
|
23
|
-
var
|
|
24
|
-
var
|
|
4
|
+
var AppLink_1 = require("@shopify/app-bridge/actions/Link/AppLink");
|
|
5
|
+
var NavigationMenu_1 = require("@shopify/app-bridge/actions/Menu/NavigationMenu");
|
|
25
6
|
var useAppBridge_1 = require("../../useAppBridge");
|
|
7
|
+
function defaultMatcher(link, location) {
|
|
8
|
+
return link.destination.replace(/\/$/, '') === location.pathname.replace(/\/$/, '');
|
|
9
|
+
}
|
|
26
10
|
function NavigationMenu(_a) {
|
|
27
|
-
var navigationLinks = _a.navigationLinks,
|
|
11
|
+
var navigationLinks = _a.navigationLinks, _b = _a.matcher, matcher = _b === void 0 ? defaultMatcher : _b;
|
|
28
12
|
var app = useAppBridge_1.useAppBridge();
|
|
29
|
-
var
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return
|
|
37
|
-
});
|
|
38
|
-
}, [app, location.pathname, matcher, navigationLinks]);
|
|
39
|
-
var navigationMenu = react_1.useMemo(function () {
|
|
40
|
-
return AppBridgeNavigationMenu.create(app, {
|
|
41
|
-
items: items,
|
|
42
|
-
active: activeLink,
|
|
13
|
+
var _c = react_1.useState(), items = _c[0], setItems = _c[1];
|
|
14
|
+
react_1.useEffect(function () {
|
|
15
|
+
var items = navigationLinks.map(function (link) { return AppLink_1.create(app, link); });
|
|
16
|
+
setItems(items);
|
|
17
|
+
}, [app, JSON.stringify(navigationLinks)]);
|
|
18
|
+
var activeLink = react_1.useMemo(function () {
|
|
19
|
+
var activeLinkIndex = (items || []).findIndex(function (link) {
|
|
20
|
+
return matcher(link, location);
|
|
43
21
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
*/
|
|
49
|
-
}, [app]);
|
|
22
|
+
if (activeLinkIndex >= 0) {
|
|
23
|
+
return items === null || items === void 0 ? void 0 : items[activeLinkIndex];
|
|
24
|
+
}
|
|
25
|
+
}, [app, location.pathname, matcher, items, location.pathname]);
|
|
50
26
|
react_1.useEffect(function () {
|
|
51
|
-
|
|
52
|
-
|
|
27
|
+
// Skip creating the navigation menu on initial render
|
|
28
|
+
if (!items) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* There isn't any advantage to keeping around a consistent instance of
|
|
33
|
+
* the navigation menu as when we create a new one it results in
|
|
34
|
+
* the same UPDATE action to be dispatched
|
|
35
|
+
*/
|
|
36
|
+
NavigationMenu_1.create(app, { items: items, active: activeLink });
|
|
37
|
+
}, [items, activeLink]);
|
|
53
38
|
return null;
|
|
54
39
|
}
|
|
55
40
|
exports.default = NavigationMenu;
|
|
@@ -3,29 +3,76 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
var react_1 = require("react");
|
|
4
4
|
var Button_1 = require("@shopify/app-bridge/actions/Button");
|
|
5
5
|
var TitleBar_1 = require("@shopify/app-bridge/actions/TitleBar");
|
|
6
|
+
var ButtonGroup_1 = require("@shopify/app-bridge/actions/ButtonGroup");
|
|
6
7
|
var transformers_1 = require("../../utilities/transformers");
|
|
7
8
|
var useAppBridge_1 = require("../../useAppBridge");
|
|
8
9
|
function TitleBar(props) {
|
|
10
|
+
var title = props.title;
|
|
9
11
|
var app = useAppBridge_1.useAppBridge();
|
|
12
|
+
var currentProps = react_1.useRef({ title: title });
|
|
10
13
|
var titleBar = react_1.useMemo(function () {
|
|
11
|
-
|
|
14
|
+
/**
|
|
15
|
+
* We purposely don't pass buttons here as they will be replaced
|
|
16
|
+
* by the subsequent useEffect to call `set` to update the options.
|
|
17
|
+
* If we pass them in here button subscriptions will be created without
|
|
18
|
+
* being cleaned up.
|
|
19
|
+
*/
|
|
20
|
+
return TitleBar_1.create(app, {});
|
|
12
21
|
}, [app]);
|
|
13
|
-
|
|
22
|
+
/**
|
|
23
|
+
* All option updates are handled in this useEffect so they can be cleaned up.
|
|
24
|
+
*/
|
|
14
25
|
react_1.useEffect(function () {
|
|
26
|
+
var _a;
|
|
15
27
|
var propsChanged = JSON.stringify(currentProps.current) !== JSON.stringify(props);
|
|
28
|
+
currentProps.current = props;
|
|
16
29
|
if (propsChanged) {
|
|
17
|
-
|
|
30
|
+
titleBar.set(transformProps(app, props));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
/**
|
|
34
|
+
* We manually update the button callbacks when no props have changed aside from the
|
|
35
|
+
* callbacks to avoid sending an unnecessary UPDATE action to the host
|
|
36
|
+
*/
|
|
37
|
+
var primaryAction = props.primaryAction, secondaryActions = props.secondaryActions, actionGroups = props.actionGroups, breadcrumbs = props.breadcrumbs;
|
|
38
|
+
var breadcrumb = Array.isArray(breadcrumbs)
|
|
39
|
+
? breadcrumbs[breadcrumbs.length - 1]
|
|
40
|
+
: breadcrumbs;
|
|
41
|
+
updateButton(breadcrumb, titleBar.options.breadcrumbs);
|
|
42
|
+
updateButton(primaryAction, (_a = titleBar.options.buttons) === null || _a === void 0 ? void 0 : _a.primary);
|
|
43
|
+
updateSecondaryActions(titleBar, secondaryActions);
|
|
44
|
+
updateActionGroups(titleBar, actionGroups);
|
|
18
45
|
}
|
|
19
|
-
titleBar.set(transformProps(app, props), propsChanged);
|
|
20
|
-
}, [titleBar, props]);
|
|
21
|
-
react_1.useEffect(function () {
|
|
22
46
|
return function () {
|
|
23
47
|
titleBar.unsubscribe();
|
|
24
48
|
};
|
|
25
|
-
}, [titleBar]);
|
|
49
|
+
}, [titleBar, props]);
|
|
26
50
|
return null;
|
|
27
51
|
}
|
|
28
52
|
exports.default = TitleBar;
|
|
53
|
+
function updateSecondaryActions(titleBar, secondaryActions) {
|
|
54
|
+
var _a, _b;
|
|
55
|
+
var secondaryButtons = ((_b = (_a = titleBar.options.buttons) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b.filter(function (button) { return !ButtonGroup_1.isGroupedButton(button); })) || [];
|
|
56
|
+
secondaryButtons === null || secondaryButtons === void 0 ? void 0 : secondaryButtons.forEach(function (secondaryButton, index) {
|
|
57
|
+
return updateButton(secondaryActions === null || secondaryActions === void 0 ? void 0 : secondaryActions[index],
|
|
58
|
+
// This needs to be casted as the React TitleBar component doesn't accept button groups for secondary actions
|
|
59
|
+
secondaryButton);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function updateActionGroups(titleBar, actionGroups) {
|
|
63
|
+
var _a, _b;
|
|
64
|
+
var actionGroupButtons = ((_b = (_a = titleBar.options.buttons) === null || _a === void 0 ? void 0 : _a.secondary) === null || _b === void 0 ? void 0 : _b.filter(ButtonGroup_1.isGroupedButton)) ||
|
|
65
|
+
[];
|
|
66
|
+
actionGroupButtons === null || actionGroupButtons === void 0 ? void 0 : actionGroupButtons.forEach(function (actionBroupButton, index) {
|
|
67
|
+
var actionGroup = actionGroups === null || actionGroups === void 0 ? void 0 : actionGroups[index];
|
|
68
|
+
if (!actionGroup) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
actionBroupButton.options.buttons.forEach(function (nestedButton, nestedIndex) {
|
|
72
|
+
return updateButton(actionGroup.actions[nestedIndex], nestedButton);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
29
76
|
function transformProps(app, _a) {
|
|
30
77
|
var actionGroups = _a.actionGroups, breadcrumbs = _a.breadcrumbs, primaryAction = _a.primaryAction, secondaryActions = _a.secondaryActions, title = _a.title;
|
|
31
78
|
var breadcrumb = Array.isArray(breadcrumbs) ? breadcrumbs[breadcrumbs.length - 1] : breadcrumbs;
|
|
@@ -39,17 +86,23 @@ function transformProps(app, _a) {
|
|
|
39
86
|
breadcrumbs: breadcrumb ? transformBreadcrumb(app, breadcrumb) : undefined,
|
|
40
87
|
};
|
|
41
88
|
}
|
|
42
|
-
function transformBreadcrumb(app, breadcrumb) {
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
89
|
+
function transformBreadcrumb(app, breadcrumb, updateBreadcrumb) {
|
|
90
|
+
var button = updateBreadcrumb ||
|
|
91
|
+
Button_1.create(app, {
|
|
92
|
+
label: breadcrumb.content || '',
|
|
93
|
+
});
|
|
94
|
+
updateButton(breadcrumb, button);
|
|
95
|
+
return button;
|
|
96
|
+
}
|
|
97
|
+
function updateButton(actionProps, button) {
|
|
98
|
+
if (!actionProps || !button) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
var redirect = transformers_1.generateRedirect(button.app, actionProps.url, actionProps.target);
|
|
48
102
|
if (redirect) {
|
|
49
|
-
button.subscribe(Button_1.Action.CLICK, redirect);
|
|
103
|
+
button.subscribe(Button_1.Action.CLICK, redirect, button);
|
|
50
104
|
}
|
|
51
|
-
if (onAction) {
|
|
52
|
-
button.subscribe(Button_1.Action.CLICK, onAction);
|
|
105
|
+
if (actionProps === null || actionProps === void 0 ? void 0 : actionProps.onAction) {
|
|
106
|
+
button.subscribe(Button_1.Action.CLICK, actionProps.onAction, button);
|
|
53
107
|
}
|
|
54
|
-
return button;
|
|
55
108
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shopify/app-bridge-react",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.26",
|
|
4
4
|
"types": "index.d.ts",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"unpkg": "umd/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
}
|
|
46
46
|
],
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@shopify/app-bridge": "^2.0.
|
|
48
|
+
"@shopify/app-bridge": "^2.0.26"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@types/react": "^17.0.38",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"react": "^16.0.0 || ^17.0.0"
|
|
57
57
|
},
|
|
58
|
-
"gitHead": "
|
|
58
|
+
"gitHead": "7ce36b7e06b45e70db3b2d360de19ec49d65f115"
|
|
59
59
|
}
|