newspack-components 4.5.0 → 4.6.0
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 +40 -0
- package/DEVELOPMENT.md +1 -1
- package/dist/cjs/accordion/index.js +43 -26
- package/dist/cjs/accordion/index.test.js +80 -0
- package/dist/cjs/accordion/style.scss +25 -21
- package/dist/cjs/action-card/style.scss +0 -22
- package/dist/cjs/breadcrumbs/index.js +80 -0
- package/dist/cjs/breadcrumbs/index.test.js +109 -0
- package/dist/cjs/breadcrumbs/style.scss +41 -0
- package/dist/cjs/card/core-card.js +8 -4
- package/dist/cjs/card/index.js +1 -1
- package/dist/cjs/card/style-core.scss +14 -0
- package/dist/cjs/card/style.scss +0 -9
- package/dist/cjs/card-feature/index.js +25 -13
- package/dist/cjs/card-settings-group/index.js +3 -0
- package/dist/cjs/confirm-dialog/index.js +34 -8
- package/dist/cjs/confirm-dialog/index.test.js +173 -0
- package/dist/cjs/divider/style.scss +4 -2
- package/dist/cjs/grid/style.scss +5 -0
- package/dist/cjs/handoff/index.js +8 -5
- package/dist/cjs/index.js +34 -1
- package/dist/cjs/integration-icon/index.js +40 -0
- package/dist/cjs/integration-icon/style.scss +42 -0
- package/dist/cjs/integration-icons/index.js +21 -2
- package/dist/cjs/modal/style.scss +4 -0
- package/dist/cjs/page/index.js +121 -0
- package/dist/cjs/page/index.test.js +69 -0
- package/dist/cjs/page/style.scss +86 -0
- package/dist/cjs/route-match.js +59 -0
- package/dist/cjs/route-match.test.js +77 -0
- package/dist/cjs/section-header/index.js +8 -1
- package/dist/cjs/section-header/style.scss +11 -11
- package/dist/cjs/select-control/GroupedSelectControl.js +1 -1
- package/dist/cjs/select-control/style.scss +4 -0
- package/dist/cjs/style.scss +1 -4
- package/dist/cjs/tabbed-navigation/index.js +188 -40
- package/dist/cjs/tabbed-navigation/index.test.js +299 -0
- package/dist/cjs/tabbed-navigation/style.scss +77 -57
- package/dist/cjs/with-wizard/index.js +34 -45
- package/dist/cjs/with-wizard-screen/index.js +82 -41
- package/dist/cjs/with-wizard-screen/index.test.js +50 -0
- package/dist/cjs/with-wizard-screen/style.scss +15 -118
- package/dist/cjs/wizard/breadcrumbs-select.js +70 -0
- package/dist/cjs/wizard/breadcrumbs-select.test.js +200 -0
- package/dist/cjs/wizard/components/WizardError.js +8 -4
- package/dist/cjs/wizard/index.js +162 -141
- package/dist/esm/accordion/index.js +42 -26
- package/dist/esm/accordion/index.test.js +79 -0
- package/dist/esm/accordion/style.scss +25 -21
- package/dist/esm/action-card/style.scss +0 -22
- package/dist/esm/breadcrumbs/index.js +75 -0
- package/dist/esm/breadcrumbs/index.test.js +105 -0
- package/dist/esm/breadcrumbs/style.scss +41 -0
- package/dist/esm/card/core-card.js +8 -4
- package/dist/esm/card/index.js +1 -1
- package/dist/esm/card/style-core.scss +14 -0
- package/dist/esm/card/style.scss +0 -9
- package/dist/esm/card-feature/index.js +25 -13
- package/dist/esm/card-settings-group/index.js +3 -0
- package/dist/esm/confirm-dialog/index.js +34 -8
- package/dist/esm/confirm-dialog/index.test.js +173 -0
- package/dist/esm/divider/style.scss +4 -2
- package/dist/esm/grid/style.scss +5 -0
- package/dist/esm/handoff/index.js +7 -5
- package/dist/esm/index.js +5 -1
- package/dist/esm/integration-icon/index.js +34 -0
- package/dist/esm/integration-icon/style.scss +42 -0
- package/dist/esm/integration-icons/index.js +22 -1
- package/dist/esm/modal/style.scss +4 -0
- package/dist/esm/page/index.js +113 -0
- package/dist/esm/page/index.test.js +65 -0
- package/dist/esm/page/style.scss +86 -0
- package/dist/esm/route-match.js +51 -0
- package/dist/esm/route-match.test.js +74 -0
- package/dist/esm/section-header/index.js +8 -1
- package/dist/esm/section-header/style.scss +11 -11
- package/dist/esm/select-control/GroupedSelectControl.js +1 -1
- package/dist/esm/select-control/style.scss +4 -0
- package/dist/esm/style.scss +1 -4
- package/dist/esm/tabbed-navigation/index.js +192 -38
- package/dist/esm/tabbed-navigation/index.test.js +296 -0
- package/dist/esm/tabbed-navigation/style.scss +77 -57
- package/dist/esm/with-wizard/index.js +33 -45
- package/dist/esm/with-wizard-screen/index.js +78 -41
- package/dist/esm/with-wizard-screen/index.test.js +46 -0
- package/dist/esm/with-wizard-screen/style.scss +15 -118
- package/dist/esm/wizard/breadcrumbs-select.js +63 -0
- package/dist/esm/wizard/breadcrumbs-select.test.js +197 -0
- package/dist/esm/wizard/components/WizardError.js +7 -5
- package/dist/esm/wizard/index.js +165 -144
- package/package.json +10 -2
- package/src/accordion/index.js +27 -15
- package/src/accordion/index.test.js +62 -0
- package/src/accordion/style.scss +25 -21
- package/src/action-card/style.scss +0 -22
- package/src/breadcrumbs/index.js +63 -0
- package/src/breadcrumbs/index.test.js +59 -0
- package/src/breadcrumbs/style.scss +41 -0
- package/src/card/core-card.js +11 -6
- package/src/card/index.js +0 -1
- package/src/card/style-core.scss +14 -0
- package/src/card/style.scss +0 -9
- package/src/card-feature/README.md +3 -3
- package/src/card-feature/index.tsx +37 -21
- package/src/card-settings-group/index.tsx +4 -0
- package/src/card-sortable-list/index.tsx +1 -1
- package/src/confirm-dialog/index.test.js +142 -0
- package/src/confirm-dialog/index.tsx +34 -7
- package/src/divider/style.scss +4 -2
- package/src/grid/style.scss +5 -0
- package/src/handoff/index.js +4 -3
- package/src/index.js +5 -1
- package/src/integration-icon/index.tsx +35 -0
- package/src/integration-icon/style.scss +42 -0
- package/src/integration-icons/index.js +23 -0
- package/src/modal/style.scss +4 -0
- package/src/page/index.js +89 -0
- package/src/page/index.test.js +43 -0
- package/src/page/style.scss +86 -0
- package/src/route-match.js +47 -0
- package/src/route-match.test.js +50 -0
- package/src/section-header/index.js +7 -3
- package/src/section-header/style.scss +11 -11
- package/src/select-control/GroupedSelectControl.js +1 -1
- package/src/select-control/style.scss +4 -0
- package/src/style.scss +1 -4
- package/src/tabbed-navigation/index.js +181 -34
- package/src/tabbed-navigation/index.test.js +228 -0
- package/src/tabbed-navigation/style.scss +77 -57
- package/src/with-wizard/index.js +18 -39
- package/src/with-wizard-screen/index.js +70 -35
- package/src/with-wizard-screen/index.test.js +36 -0
- package/src/with-wizard-screen/style.scss +15 -118
- package/src/wizard/breadcrumbs-select.js +51 -0
- package/src/wizard/breadcrumbs-select.test.js +124 -0
- package/src/wizard/components/WizardError.js +4 -3
- package/src/wizard/index.js +160 -146
- package/tsconfig.json +7 -0
|
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports["default"] = void 0;
|
|
8
8
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
9
|
var _i18n = require("@wordpress/i18n");
|
|
10
|
+
var _element = require("@wordpress/element");
|
|
10
11
|
var _components = require("@wordpress/components");
|
|
11
12
|
var _icons = require("@wordpress/icons");
|
|
12
13
|
var _badge = _interopRequireDefault(require("../badge"));
|
|
@@ -45,6 +46,8 @@ var CardFeature = function CardFeature(_ref) {
|
|
|
45
46
|
_ref$requirementsActi = _ref.requirementsActionable,
|
|
46
47
|
requirementsActionable = _ref$requirementsActi === void 0 ? false : _ref$requirementsActi,
|
|
47
48
|
enableLabel = _ref.enableLabel,
|
|
49
|
+
_ref$busy = _ref.busy,
|
|
50
|
+
busy = _ref$busy === void 0 ? false : _ref$busy,
|
|
48
51
|
configureLabel = _ref.configureLabel,
|
|
49
52
|
onEnable = _ref.onEnable,
|
|
50
53
|
onConfigure = _ref.onConfigure,
|
|
@@ -71,6 +74,7 @@ var CardFeature = function CardFeature(_ref) {
|
|
|
71
74
|
}
|
|
72
75
|
var isConfigureState = enabled && !requirements;
|
|
73
76
|
var buttonLabel = isConfigureState ? configureLabel !== null && configureLabel !== void 0 ? configureLabel : (0, _i18n.__)('Configure', 'newspack-plugin') : enableLabel !== null && enableLabel !== void 0 ? enableLabel : (0, _i18n.__)('Enable', 'newspack-plugin');
|
|
77
|
+
var showMoreControls = enabled && !!(moreControls !== null && moreControls !== void 0 && moreControls.length) && (!requirements || requirementsActionable);
|
|
74
78
|
var handleButtonClick = function handleButtonClick() {
|
|
75
79
|
if (isConfigureState) {
|
|
76
80
|
onConfigure === null || onConfigure === void 0 || onConfigure();
|
|
@@ -78,10 +82,24 @@ var CardFeature = function CardFeature(_ref) {
|
|
|
78
82
|
onEnable === null || onEnable === void 0 || onEnable();
|
|
79
83
|
}
|
|
80
84
|
};
|
|
81
|
-
var
|
|
82
|
-
|
|
83
|
-
'newspack-card-feature__icon--radius-
|
|
85
|
+
var iconDescriptor = icon && !(0, _element.isValidElement)(icon) ? icon : null;
|
|
86
|
+
var iconClasses = iconDescriptor ? (0, _classnames["default"])('newspack-card-feature__icon', {
|
|
87
|
+
'newspack-card-feature__icon--radius-small': !!iconDescriptor.backgroundColor && iconDescriptor.radius !== 'full',
|
|
88
|
+
'newspack-card-feature__icon--radius-full': iconDescriptor.radius === 'full'
|
|
84
89
|
}) : undefined;
|
|
90
|
+
var renderedIcon = null;
|
|
91
|
+
if ((0, _element.isValidElement)(icon)) {
|
|
92
|
+
renderedIcon = icon;
|
|
93
|
+
} else if (iconDescriptor) {
|
|
94
|
+
renderedIcon = /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
95
|
+
className: iconClasses,
|
|
96
|
+
style: {
|
|
97
|
+
backgroundColor: iconDescriptor.backgroundColor,
|
|
98
|
+
color: iconDescriptor.fill
|
|
99
|
+
},
|
|
100
|
+
children: iconDescriptor.node
|
|
101
|
+
});
|
|
102
|
+
}
|
|
85
103
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_card["default"], {
|
|
86
104
|
className: classes,
|
|
87
105
|
__experimentalCoreCard: true,
|
|
@@ -102,14 +120,7 @@ var CardFeature = function CardFeature(_ref) {
|
|
|
102
120
|
className: "newspack-card-feature__description",
|
|
103
121
|
children: description
|
|
104
122
|
})]
|
|
105
|
-
}),
|
|
106
|
-
className: iconClasses,
|
|
107
|
-
style: {
|
|
108
|
-
backgroundColor: icon.backgroundColor,
|
|
109
|
-
color: icon.fill
|
|
110
|
-
},
|
|
111
|
-
children: icon.node
|
|
112
|
-
})]
|
|
123
|
+
}), renderedIcon]
|
|
113
124
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalHStack, {
|
|
114
125
|
alignment: "edge",
|
|
115
126
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalHStack, {
|
|
@@ -117,11 +128,12 @@ var CardFeature = function CardFeature(_ref) {
|
|
|
117
128
|
spacing: "8px",
|
|
118
129
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_button["default"], {
|
|
119
130
|
variant: isConfigureState ? 'tertiary' : 'secondary',
|
|
120
|
-
disabled: isMuted && !requirementsActionable,
|
|
131
|
+
disabled: isMuted && !requirementsActionable || busy,
|
|
132
|
+
isBusy: busy,
|
|
121
133
|
onClick: handleButtonClick,
|
|
122
134
|
size: "compact",
|
|
123
135
|
children: buttonLabel
|
|
124
|
-
}),
|
|
136
|
+
}), showMoreControls && /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.DropdownMenu, {
|
|
125
137
|
icon: _icons.moreVertical,
|
|
126
138
|
label: (0, _i18n.__)('More', 'newspack-plugin'),
|
|
127
139
|
controls: moreControls,
|
|
@@ -30,6 +30,8 @@ var CardSettingsGroup = function CardSettingsGroup(_ref) {
|
|
|
30
30
|
disabled = _ref$disabled === void 0 ? false : _ref$disabled,
|
|
31
31
|
_ref$icon = _ref.icon,
|
|
32
32
|
icon = _ref$icon === void 0 ? null : _ref$icon,
|
|
33
|
+
_ref$iconElement = _ref.iconElement,
|
|
34
|
+
iconElement = _ref$iconElement === void 0 ? null : _ref$iconElement,
|
|
33
35
|
headerAction = _ref.headerAction,
|
|
34
36
|
_ref$title = _ref.title,
|
|
35
37
|
title = _ref$title === void 0 ? '' : _ref$title,
|
|
@@ -58,6 +60,7 @@ var CardSettingsGroup = function CardSettingsGroup(_ref) {
|
|
|
58
60
|
onToggle: onEnable,
|
|
59
61
|
disabled: disabled,
|
|
60
62
|
icon: icon,
|
|
63
|
+
iconElement: iconElement,
|
|
61
64
|
iconBackgroundColor: true,
|
|
62
65
|
isActive: isActive,
|
|
63
66
|
title: title
|
|
@@ -13,7 +13,7 @@ var _element = require("@wordpress/element");
|
|
|
13
13
|
var _router = _interopRequireDefault(require("../proxied-imports/router"));
|
|
14
14
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
15
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
|
-
var _excluded = ["className", "size", "hideTitle", "isDestructive", "onConfirm", "onCancel", "when", "isOpen"];
|
|
16
|
+
var _excluded = ["className", "size", "hideTitle", "isDestructive", "onConfirm", "onCancel", "when", "isOpen", "children"];
|
|
17
17
|
/**
|
|
18
18
|
* Modal
|
|
19
19
|
*/
|
|
@@ -59,6 +59,7 @@ function ConfirmDialog(_ref, ref) {
|
|
|
59
59
|
when = _ref$when === void 0 ? false : _ref$when,
|
|
60
60
|
_ref$isOpen = _ref.isOpen,
|
|
61
61
|
isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen,
|
|
62
|
+
children = _ref.children,
|
|
62
63
|
otherProps = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
|
|
63
64
|
var _useState = (0, _element.useState)(isOpen),
|
|
64
65
|
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
@@ -66,6 +67,9 @@ function ConfirmDialog(_ref, ref) {
|
|
|
66
67
|
setShowDialog = _useState2[1];
|
|
67
68
|
var history = useHistory();
|
|
68
69
|
var pendingNavigation = (0, _element.useRef)(null);
|
|
70
|
+
// While true, the blocker lets navigation through — used so the confirmed
|
|
71
|
+
// ("Discard changes") navigation isn't caught by the still-active blocker.
|
|
72
|
+
var bypassBlock = (0, _element.useRef)(false);
|
|
69
73
|
var handleOnConfirm = (0, _element.useCallback)(function () {
|
|
70
74
|
var _pendingNavigation$cu;
|
|
71
75
|
setShowDialog(false);
|
|
@@ -76,8 +80,16 @@ function ConfirmDialog(_ref, ref) {
|
|
|
76
80
|
var handleOnCancel = (0, _element.useCallback)(function () {
|
|
77
81
|
setShowDialog(false);
|
|
78
82
|
pendingNavigation.current = null;
|
|
83
|
+
// A POP may have moved the URL to the target before it was blocked; put
|
|
84
|
+
// it back so the address bar matches the page the user chose to stay on.
|
|
85
|
+
bypassBlock.current = true;
|
|
86
|
+
try {
|
|
87
|
+
history.replace(history.location);
|
|
88
|
+
} finally {
|
|
89
|
+
bypassBlock.current = false;
|
|
90
|
+
}
|
|
79
91
|
onCancel();
|
|
80
|
-
}, [onCancel,
|
|
92
|
+
}, [onCancel, history]);
|
|
81
93
|
|
|
82
94
|
// Block navigation when there are unsaved changes.
|
|
83
95
|
(0, _element.useEffect)(function () {
|
|
@@ -85,12 +97,25 @@ function ConfirmDialog(_ref, ref) {
|
|
|
85
97
|
return;
|
|
86
98
|
}
|
|
87
99
|
var unblock = history.block(function (location, action) {
|
|
100
|
+
// Let our own confirmed navigation through instead of re-blocking it.
|
|
101
|
+
if (bypassBlock.current) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
88
104
|
pendingNavigation.current = function () {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
105
|
+
bypassBlock.current = true;
|
|
106
|
+
try {
|
|
107
|
+
// A browser/anchor POP (e.g. a breadcrumb or back link) moves the URL
|
|
108
|
+
// to the target before navigation is blocked, and v5 leaves the hash
|
|
109
|
+
// there, so pushing the target would be a no-op. Re-sync to the
|
|
110
|
+
// still-current location first so the real navigation actually fires.
|
|
111
|
+
history.replace(history.location);
|
|
112
|
+
if (action === 'REPLACE') {
|
|
113
|
+
history.replace(location);
|
|
114
|
+
} else {
|
|
115
|
+
history.push(location);
|
|
116
|
+
}
|
|
117
|
+
} finally {
|
|
118
|
+
bypassBlock.current = false;
|
|
94
119
|
}
|
|
95
120
|
};
|
|
96
121
|
setShowDialog(true);
|
|
@@ -117,7 +142,8 @@ function ConfirmDialog(_ref, ref) {
|
|
|
117
142
|
ref: ref,
|
|
118
143
|
onConfirm: handleOnConfirm,
|
|
119
144
|
onCancel: handleOnCancel,
|
|
120
|
-
__experimentalHideHeader: false
|
|
145
|
+
__experimentalHideHeader: false,
|
|
146
|
+
children: children
|
|
121
147
|
}));
|
|
122
148
|
}
|
|
123
149
|
var _default = exports["default"] = (0, _element.forwardRef)(ConfirmDialog);
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
5
|
+
var _react = require("@testing-library/react");
|
|
6
|
+
var _reactRouterDom = require("react-router-dom");
|
|
7
|
+
var _ = _interopRequireDefault(require("./"));
|
|
8
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
9
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
10
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /**
|
|
11
|
+
* External dependencies.
|
|
12
|
+
*/ /**
|
|
13
|
+
* Internal dependencies.
|
|
14
|
+
*/
|
|
15
|
+
var HistoryGrabber = function HistoryGrabber(_ref) {
|
|
16
|
+
var historyRef = _ref.historyRef;
|
|
17
|
+
historyRef.current = (0, _reactRouterDom.useHistory)();
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
var renderWithHistory = function renderWithHistory() {
|
|
21
|
+
var routerProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
22
|
+
var historyRef = {
|
|
23
|
+
current: null
|
|
24
|
+
};
|
|
25
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.MemoryRouter, _objectSpread(_objectSpread({}, routerProps), {}, {
|
|
26
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(HistoryGrabber, {
|
|
27
|
+
historyRef: historyRef
|
|
28
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
29
|
+
when: true,
|
|
30
|
+
confirmButtonText: "Discard changes",
|
|
31
|
+
cancelButtonText: "Keep editing",
|
|
32
|
+
children: "Unsaved changes"
|
|
33
|
+
})]
|
|
34
|
+
})));
|
|
35
|
+
return historyRef.current;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// The modal's X close button reuses the cancel label as its aria-label, so
|
|
39
|
+
// query by visible text to hit the actual footer buttons.
|
|
40
|
+
var confirmNavigation = function confirmNavigation() {
|
|
41
|
+
return _react.fireEvent.click(_react.screen.getByText('Discard changes', {
|
|
42
|
+
selector: 'button'
|
|
43
|
+
}));
|
|
44
|
+
};
|
|
45
|
+
var cancelNavigation = function cancelNavigation() {
|
|
46
|
+
return _react.fireEvent.click(_react.screen.getByText('Keep editing', {
|
|
47
|
+
selector: 'button'
|
|
48
|
+
}));
|
|
49
|
+
};
|
|
50
|
+
var dialog = function dialog() {
|
|
51
|
+
return _react.screen.queryByText('Unsaved changes');
|
|
52
|
+
};
|
|
53
|
+
describe('ConfirmDialog navigation blocking', function () {
|
|
54
|
+
it('blocks navigation and stays on the current page on cancel', function () {
|
|
55
|
+
var history = renderWithHistory();
|
|
56
|
+
(0, _react.act)(function () {
|
|
57
|
+
return history.push('/next');
|
|
58
|
+
});
|
|
59
|
+
expect(dialog()).toBeInTheDocument();
|
|
60
|
+
expect(history.location.pathname).toBe('/');
|
|
61
|
+
var replaceSpy = jest.spyOn(history, 'replace');
|
|
62
|
+
cancelNavigation();
|
|
63
|
+
expect(dialog()).not.toBeInTheDocument();
|
|
64
|
+
// The URL is re-synced to the page the user chose to stay on.
|
|
65
|
+
expect(replaceSpy).toHaveBeenCalledTimes(1);
|
|
66
|
+
expect(history.location.pathname).toBe('/');
|
|
67
|
+
});
|
|
68
|
+
it('replays a blocked push on confirm: re-sync replace first, then push, and re-arms the blocker', function () {
|
|
69
|
+
var history = renderWithHistory();
|
|
70
|
+
var replaceSpy = jest.spyOn(history, 'replace');
|
|
71
|
+
var pushSpy = jest.spyOn(history, 'push');
|
|
72
|
+
(0, _react.act)(function () {
|
|
73
|
+
return history.push('/next');
|
|
74
|
+
});
|
|
75
|
+
expect(history.location.pathname).toBe('/');
|
|
76
|
+
confirmNavigation();
|
|
77
|
+
expect(history.location.pathname).toBe('/next');
|
|
78
|
+
|
|
79
|
+
// Replay order: re-sync replace fires before the target push.
|
|
80
|
+
var resyncOrder = replaceSpy.mock.invocationCallOrder[0];
|
|
81
|
+
var replayOrder = pushSpy.mock.invocationCallOrder[1];
|
|
82
|
+
expect(replaceSpy).toHaveBeenCalledTimes(1);
|
|
83
|
+
expect(pushSpy).toHaveBeenCalledTimes(2);
|
|
84
|
+
expect(resyncOrder).toBeLessThan(replayOrder);
|
|
85
|
+
|
|
86
|
+
// The bypass only lets the confirmed navigation through; the next one is blocked again.
|
|
87
|
+
(0, _react.act)(function () {
|
|
88
|
+
return history.push('/another');
|
|
89
|
+
});
|
|
90
|
+
expect(history.location.pathname).toBe('/next');
|
|
91
|
+
expect(dialog()).toBeInTheDocument();
|
|
92
|
+
});
|
|
93
|
+
it('replays a blocked REPLACE with replace, not push', function () {
|
|
94
|
+
var history = renderWithHistory();
|
|
95
|
+
var pushSpy = jest.spyOn(history, 'push');
|
|
96
|
+
(0, _react.act)(function () {
|
|
97
|
+
return history.replace('/replaced');
|
|
98
|
+
});
|
|
99
|
+
expect(dialog()).toBeInTheDocument();
|
|
100
|
+
expect(history.location.pathname).toBe('/');
|
|
101
|
+
confirmNavigation();
|
|
102
|
+
expect(history.location.pathname).toBe('/replaced');
|
|
103
|
+
expect(pushSpy).not.toHaveBeenCalled();
|
|
104
|
+
expect(history.length).toBe(1);
|
|
105
|
+
});
|
|
106
|
+
it('replays a blocked POP (back navigation) as a push after the re-sync', function () {
|
|
107
|
+
var history = renderWithHistory({
|
|
108
|
+
initialEntries: ['/start', '/current'],
|
|
109
|
+
initialIndex: 1
|
|
110
|
+
});
|
|
111
|
+
(0, _react.act)(function () {
|
|
112
|
+
return history.goBack();
|
|
113
|
+
});
|
|
114
|
+
expect(dialog()).toBeInTheDocument();
|
|
115
|
+
expect(history.location.pathname).toBe('/current');
|
|
116
|
+
confirmNavigation();
|
|
117
|
+
expect(history.location.pathname).toBe('/start');
|
|
118
|
+
// Pushed rather than popped: the target becomes a new forward entry.
|
|
119
|
+
expect(history.length).toBe(3);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// React re-reports errors thrown in event handlers as uncaught window
|
|
123
|
+
// errors; swallow them so the intentional throws don't fail the test.
|
|
124
|
+
var withNavigationError = function withNavigationError(fn) {
|
|
125
|
+
var consoleError = jest.spyOn(console, 'error').mockImplementation(function () {});
|
|
126
|
+
var onWindowError = function onWindowError(event) {
|
|
127
|
+
return event.preventDefault();
|
|
128
|
+
};
|
|
129
|
+
window.addEventListener('error', onWindowError);
|
|
130
|
+
try {
|
|
131
|
+
fn();
|
|
132
|
+
} finally {
|
|
133
|
+
window.removeEventListener('error', onWindowError);
|
|
134
|
+
consoleError.mockRestore();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
it('keeps blocking after a confirmed navigation throws', function () {
|
|
138
|
+
var history = renderWithHistory();
|
|
139
|
+
(0, _react.act)(function () {
|
|
140
|
+
return history.push('/next');
|
|
141
|
+
});
|
|
142
|
+
jest.spyOn(history, 'push').mockImplementationOnce(function () {
|
|
143
|
+
throw new Error('nav failed');
|
|
144
|
+
});
|
|
145
|
+
withNavigationError(function () {
|
|
146
|
+
return confirmNavigation();
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// bypassBlock was reset by the finally, so navigation is still protected.
|
|
150
|
+
(0, _react.act)(function () {
|
|
151
|
+
return history.push('/elsewhere');
|
|
152
|
+
});
|
|
153
|
+
expect(history.location.pathname).toBe('/');
|
|
154
|
+
expect(dialog()).toBeInTheDocument();
|
|
155
|
+
});
|
|
156
|
+
it('keeps blocking after a cancel URL re-sync throws', function () {
|
|
157
|
+
var history = renderWithHistory();
|
|
158
|
+
(0, _react.act)(function () {
|
|
159
|
+
return history.push('/next');
|
|
160
|
+
});
|
|
161
|
+
jest.spyOn(history, 'replace').mockImplementationOnce(function () {
|
|
162
|
+
throw new Error('replace failed');
|
|
163
|
+
});
|
|
164
|
+
withNavigationError(function () {
|
|
165
|
+
return cancelNavigation();
|
|
166
|
+
});
|
|
167
|
+
(0, _react.act)(function () {
|
|
168
|
+
return history.push('/elsewhere');
|
|
169
|
+
});
|
|
170
|
+
expect(history.location.pathname).toBe('/');
|
|
171
|
+
expect(dialog()).toBeInTheDocument();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
// Variant
|
|
35
35
|
|
|
36
36
|
&--variant-default {
|
|
37
|
-
background-color: wp-colors.$gray-300;
|
|
37
|
+
background-color: var( --wpds-color-stroke-surface-neutral, #{wp-colors.$gray-300} );
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
&--variant-primary {
|
|
@@ -46,6 +46,8 @@
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
&--variant-tertiary {
|
|
49
|
-
|
|
49
|
+
// Fallback for consumers whose bundle doesn't carry the wpds token sheet
|
|
50
|
+
// (it ships with the Page header's stylesheet).
|
|
51
|
+
background-color: var( --wpds-color-stroke-surface-neutral-weak, #{wp-colors.$gray-100} );
|
|
50
52
|
}
|
|
51
53
|
}
|
package/dist/cjs/grid/style.scss
CHANGED
|
@@ -14,6 +14,7 @@ var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits
|
|
|
14
14
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
15
15
|
var _apiFetch = _interopRequireDefault(require("@wordpress/api-fetch"));
|
|
16
16
|
var _element = require("@wordpress/element");
|
|
17
|
+
var _components = require("@wordpress/components");
|
|
17
18
|
var _i18n = require("@wordpress/i18n");
|
|
18
19
|
var _ = require("../");
|
|
19
20
|
var _assign = _interopRequireDefault(require("lodash/assign"));
|
|
@@ -27,7 +28,8 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
27
28
|
* Handoff
|
|
28
29
|
*/ /**
|
|
29
30
|
* WordPress dependencies.
|
|
30
|
-
*/
|
|
31
|
+
*/ // eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
32
|
+
/**
|
|
31
33
|
* Internal dependencies.
|
|
32
34
|
*/ /**
|
|
33
35
|
* External dependencies.
|
|
@@ -202,10 +204,11 @@ var Handoff = /*#__PURE__*/function (_Component) {
|
|
|
202
204
|
},
|
|
203
205
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
|
|
204
206
|
children: modalBody
|
|
205
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalHStack, {
|
|
208
|
+
justify: "flex-end",
|
|
209
|
+
spacing: 4,
|
|
210
|
+
wrap: true,
|
|
211
|
+
className: "newspack-modal__footer",
|
|
209
212
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_.Button, {
|
|
210
213
|
variant: "secondary",
|
|
211
214
|
onClick: function onClick() {
|
package/dist/cjs/index.js
CHANGED
|
@@ -10,6 +10,12 @@ Object.defineProperty(exports, "Accordion", {
|
|
|
10
10
|
return _accordion["default"];
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
|
+
Object.defineProperty(exports, "AccordionPanel", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function get() {
|
|
16
|
+
return _accordion.AccordionPanel;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
13
19
|
Object.defineProperty(exports, "ActionCard", {
|
|
14
20
|
enumerable: true,
|
|
15
21
|
get: function get() {
|
|
@@ -46,6 +52,12 @@ Object.defineProperty(exports, "BoxContrast", {
|
|
|
46
52
|
return _boxContrast["default"];
|
|
47
53
|
}
|
|
48
54
|
});
|
|
55
|
+
Object.defineProperty(exports, "Breadcrumbs", {
|
|
56
|
+
enumerable: true,
|
|
57
|
+
get: function get() {
|
|
58
|
+
return _breadcrumbs["default"];
|
|
59
|
+
}
|
|
60
|
+
});
|
|
49
61
|
Object.defineProperty(exports, "Button", {
|
|
50
62
|
enumerable: true,
|
|
51
63
|
get: function get() {
|
|
@@ -166,6 +178,12 @@ Object.defineProperty(exports, "InfoButton", {
|
|
|
166
178
|
return _infoButton["default"];
|
|
167
179
|
}
|
|
168
180
|
});
|
|
181
|
+
Object.defineProperty(exports, "IntegrationIcon", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
get: function get() {
|
|
184
|
+
return _integrationIcon["default"];
|
|
185
|
+
}
|
|
186
|
+
});
|
|
169
187
|
Object.defineProperty(exports, "Modal", {
|
|
170
188
|
enumerable: true,
|
|
171
189
|
get: function get() {
|
|
@@ -184,6 +202,12 @@ Object.defineProperty(exports, "Notice", {
|
|
|
184
202
|
return _notice["default"];
|
|
185
203
|
}
|
|
186
204
|
});
|
|
205
|
+
Object.defineProperty(exports, "Page", {
|
|
206
|
+
enumerable: true,
|
|
207
|
+
get: function get() {
|
|
208
|
+
return _page["default"];
|
|
209
|
+
}
|
|
210
|
+
});
|
|
187
211
|
Object.defineProperty(exports, "PluginInstaller", {
|
|
188
212
|
enumerable: true,
|
|
189
213
|
get: function get() {
|
|
@@ -292,6 +316,12 @@ Object.defineProperty(exports, "Wizard", {
|
|
|
292
316
|
return _wizard["default"];
|
|
293
317
|
}
|
|
294
318
|
});
|
|
319
|
+
Object.defineProperty(exports, "espProviderOrder", {
|
|
320
|
+
enumerable: true,
|
|
321
|
+
get: function get() {
|
|
322
|
+
return integrationIcons.espProviderOrder;
|
|
323
|
+
}
|
|
324
|
+
});
|
|
295
325
|
Object.defineProperty(exports, "hooks", {
|
|
296
326
|
enumerable: true,
|
|
297
327
|
get: function get() {
|
|
@@ -329,12 +359,13 @@ Object.defineProperty(exports, "withWizardScreen", {
|
|
|
329
359
|
return _withWizardScreen["default"];
|
|
330
360
|
}
|
|
331
361
|
});
|
|
332
|
-
var _accordion =
|
|
362
|
+
var _accordion = _interopRequireWildcard(require("./accordion"));
|
|
333
363
|
var _actionCard = _interopRequireDefault(require("./action-card"));
|
|
334
364
|
var _autocompleteTokenfield = _interopRequireDefault(require("./autocomplete-tokenfield"));
|
|
335
365
|
var _autocompleteWithSuggestions = _interopRequireDefault(require("./autocomplete-with-suggestions"));
|
|
336
366
|
var _autocompleteWithLatestPosts = _interopRequireDefault(require("./autocomplete-with-latest-posts"));
|
|
337
367
|
var _badge = _interopRequireDefault(require("./badge"));
|
|
368
|
+
var _breadcrumbs = _interopRequireDefault(require("./breadcrumbs"));
|
|
338
369
|
var _button = _interopRequireDefault(require("./button"));
|
|
339
370
|
var _boxContrast = _interopRequireDefault(require("./box-contrast"));
|
|
340
371
|
var _card = _interopRequireDefault(require("./card"));
|
|
@@ -342,6 +373,7 @@ var _cardFeature = _interopRequireDefault(require("./card-feature"));
|
|
|
342
373
|
var _cardForm = _interopRequireDefault(require("./card-form"));
|
|
343
374
|
var _cardSettingsGroup = _interopRequireDefault(require("./card-settings-group"));
|
|
344
375
|
var _cardSortableList = _interopRequireDefault(require("./card-sortable-list"));
|
|
376
|
+
var _integrationIcon = _interopRequireDefault(require("./integration-icon"));
|
|
345
377
|
var _categoryAutocomplete = _interopRequireDefault(require("./category-autocomplete"));
|
|
346
378
|
var _colorPicker = _interopRequireDefault(require("./color-picker"));
|
|
347
379
|
var _confirmDialog = _interopRequireDefault(require("./confirm-dialog"));
|
|
@@ -359,6 +391,7 @@ var _grid = _interopRequireDefault(require("./grid"));
|
|
|
359
391
|
var _modal = _interopRequireDefault(require("./modal"));
|
|
360
392
|
var _newspackIcon = _interopRequireDefault(require("./newspack-icon"));
|
|
361
393
|
var _notice = _interopRequireDefault(require("./notice"));
|
|
394
|
+
var _page = _interopRequireDefault(require("./page"));
|
|
362
395
|
var _pluginInstaller = _interopRequireDefault(require("./plugin-installer"));
|
|
363
396
|
var _pluginSettings = _interopRequireDefault(require("./plugin-settings"));
|
|
364
397
|
var _pluginToggle = _interopRequireDefault(require("./plugin-toggle"));
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
var _integrationIcons = require("../integration-icons");
|
|
10
|
+
require("./style.scss");
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
/**
|
|
13
|
+
* External dependencies
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Internal dependencies
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The single source for how an ESP provider is shown: brand mark plus badge
|
|
22
|
+
* background. A new provider needs an icon file, an `espProviderIcons` entry,
|
|
23
|
+
* and a background rule in this component's stylesheet.
|
|
24
|
+
*/var IntegrationIcon = function IntegrationIcon(_ref) {
|
|
25
|
+
var provider = _ref.provider,
|
|
26
|
+
className = _ref.className;
|
|
27
|
+
var icons = _integrationIcons.espProviderIcons;
|
|
28
|
+
var node = Object.prototype.hasOwnProperty.call(_integrationIcons.espProviderIcons, provider) ? icons[provider] : null;
|
|
29
|
+
if (!node) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
// Decorative: the provider is always named in adjacent visible text (the card
|
|
33
|
+
// title), so hide the mark from assistive tech to avoid duplicate announcements.
|
|
34
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
35
|
+
"aria-hidden": "true",
|
|
36
|
+
className: (0, _classnames["default"])('newspack-integration-icon', "newspack-integration-icon--".concat(provider.replace(/_/g, '-')), className),
|
|
37
|
+
children: node
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
var _default = exports["default"] = IntegrationIcon;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
2
|
+
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
3
|
+
|
|
4
|
+
.newspack-integration-icon {
|
|
5
|
+
align-items: center;
|
|
6
|
+
border-radius: wp-vars.$radius-round;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex: 0 0 wp-vars.$grid-unit-50;
|
|
9
|
+
height: wp-vars.$grid-unit-50;
|
|
10
|
+
justify-content: center;
|
|
11
|
+
width: wp-vars.$grid-unit-50;
|
|
12
|
+
|
|
13
|
+
svg {
|
|
14
|
+
display: block;
|
|
15
|
+
fill: currentcolor;
|
|
16
|
+
height: wp-vars.$grid-unit-30;
|
|
17
|
+
width: wp-vars.$grid-unit-30;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&--active-campaign {
|
|
21
|
+
background: #004cff;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&--mailchimp {
|
|
25
|
+
background: #ffe01b;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&--constant-contact {
|
|
29
|
+
background: wp-colors.$gray-100;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&--manual {
|
|
33
|
+
background: wp-colors.$gray-800;
|
|
34
|
+
color: wp-colors.$white;
|
|
35
|
+
|
|
36
|
+
// Set the fill on the path directly so the card's active/hover state
|
|
37
|
+
// (which recolours header svgs) can't override the white manual mark.
|
|
38
|
+
svg path {
|
|
39
|
+
fill: currentcolor;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -16,6 +16,7 @@ Object.defineProperty(exports, "constantContact", {
|
|
|
16
16
|
return _constantContact["default"];
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
|
+
exports.espProviderOrder = exports.espProviderIcons = void 0;
|
|
19
20
|
Object.defineProperty(exports, "fundraiseUp", {
|
|
20
21
|
enumerable: true,
|
|
21
22
|
get: function get() {
|
|
@@ -40,9 +41,27 @@ Object.defineProperty(exports, "wisepops", {
|
|
|
40
41
|
return _wisepops["default"];
|
|
41
42
|
}
|
|
42
43
|
});
|
|
44
|
+
var _icons = require("@wordpress/icons");
|
|
43
45
|
var _activeCampaign = _interopRequireDefault(require("./active-campaign"));
|
|
44
46
|
var _constantContact = _interopRequireDefault(require("./constant-contact"));
|
|
45
|
-
var _fundraiseUp = _interopRequireDefault(require("./fundraise-up"));
|
|
46
47
|
var _mailchimp = _interopRequireDefault(require("./mailchimp"));
|
|
48
|
+
var _fundraiseUp = _interopRequireDefault(require("./fundraise-up"));
|
|
47
49
|
var _salesforce = _interopRequireDefault(require("./salesforce"));
|
|
48
|
-
var _wisepops = _interopRequireDefault(require("./wisepops"));
|
|
50
|
+
var _wisepops = _interopRequireDefault(require("./wisepops"));
|
|
51
|
+
/**
|
|
52
|
+
* WordPress dependencies
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Internal dependencies
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
// ESP provider brand marks keyed by the slug the backend reports
|
|
60
|
+
// (`Newspack_Newsletters::service_provider()`). Rendered via IntegrationIcon.
|
|
61
|
+
var espProviderIcons = exports.espProviderIcons = {
|
|
62
|
+
active_campaign: _activeCampaign["default"],
|
|
63
|
+
mailchimp: _mailchimp["default"],
|
|
64
|
+
constant_contact: _constantContact["default"],
|
|
65
|
+
manual: _icons.atSymbol
|
|
66
|
+
};
|
|
67
|
+
var espProviderOrder = exports.espProviderOrder = ['active_campaign', 'mailchimp', 'constant_contact', 'manual'];
|