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
|
@@ -2,17 +2,19 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
2
|
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; }
|
|
3
3
|
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) { _defineProperty(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; }
|
|
4
4
|
/**
|
|
5
|
-
* WordPress dependencies
|
|
5
|
+
* WordPress dependencies
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import { category } from '@wordpress/icons';
|
|
7
|
+
import { cloneElement } from '@wordpress/element';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Internal dependencies
|
|
12
11
|
*/
|
|
13
|
-
import { Button, Handoff,
|
|
12
|
+
import { Button, Handoff, Notice, HandoffMessage, TabbedNavigation, Page } from '../';
|
|
13
|
+
import { activeBreadcrumbs } from '../wizard/breadcrumbs-select';
|
|
14
14
|
import { buttonProps } from '../button-props';
|
|
15
|
+
import Router from '../proxied-imports/router';
|
|
15
16
|
import './style.scss';
|
|
17
|
+
var useLocation = Router.useLocation;
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* External dependencies
|
|
@@ -20,12 +22,31 @@ import './style.scss';
|
|
|
20
22
|
import classnames from 'classnames';
|
|
21
23
|
|
|
22
24
|
/**
|
|
23
|
-
*
|
|
25
|
+
* Derives the active-tab breadcrumb trail from the current route. Only rendered
|
|
26
|
+
* for tabbed wizards, which always mount inside a Router, so calling useLocation
|
|
27
|
+
* here keeps router-free consumers (e.g. standalone multibranded) from crashing.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object} props Component props.
|
|
30
|
+
* @param {Array} props.sections Tabbed navigation sections.
|
|
31
|
+
* @param {Function} props.render Renders the page given the breadcrumb trail.
|
|
32
|
+
* @return {JSX.Element} The rendered page.
|
|
24
33
|
*/
|
|
25
34
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
35
|
+
var RouteBreadcrumbs = function RouteBreadcrumbs(_ref) {
|
|
36
|
+
var sections = _ref.sections,
|
|
37
|
+
render = _ref.render;
|
|
38
|
+
var _useLocation = useLocation(),
|
|
39
|
+
pathname = _useLocation.pathname;
|
|
40
|
+
return render(activeBreadcrumbs(sections, pathname));
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Higher-Order Component to provide plugin management and error handling to Newspack Wizards.
|
|
45
|
+
*/
|
|
26
46
|
export default function withWizardScreen(WrappedComponent) {
|
|
27
|
-
var
|
|
28
|
-
hidePrimaryButton =
|
|
47
|
+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
|
|
48
|
+
hidePrimaryButton = _ref2.hidePrimaryButton,
|
|
49
|
+
hideHeader = _ref2.hideHeader;
|
|
29
50
|
var WrappedWithWizardScreen = function WrappedWithWizardScreen(props) {
|
|
30
51
|
var className = props.className,
|
|
31
52
|
buttonText = props.buttonText,
|
|
@@ -34,6 +55,8 @@ export default function withWizardScreen(WrappedComponent) {
|
|
|
34
55
|
headerText = props.headerText,
|
|
35
56
|
subHeaderText = props.subHeaderText,
|
|
36
57
|
tabbedNavigation = props.tabbedNavigation,
|
|
58
|
+
breadcrumbItems = props.breadcrumbItems,
|
|
59
|
+
headerActions = props.headerActions,
|
|
37
60
|
secondaryButtonText = props.secondaryButtonText,
|
|
38
61
|
secondaryButtonAction = props.secondaryButtonAction,
|
|
39
62
|
renderAboveContent = props.renderAboveContent,
|
|
@@ -59,40 +82,14 @@ export default function withWizardScreen(WrappedComponent) {
|
|
|
59
82
|
children: buttonText
|
|
60
83
|
}, retrievedButtonProps), overridingProps));
|
|
61
84
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
className: "newspack-wizard__title",
|
|
71
|
-
children: [/*#__PURE__*/_jsx(Button, {
|
|
72
|
-
isLink: true,
|
|
73
|
-
href: newspack_urls.dashboard,
|
|
74
|
-
label: __('Return to Dashboard', 'newspack-plugin'),
|
|
75
|
-
showTooltip: true,
|
|
76
|
-
icon: category,
|
|
77
|
-
iconSize: 36,
|
|
78
|
-
children: /*#__PURE__*/_jsx(NewspackIcon, {
|
|
79
|
-
size: 36
|
|
80
|
-
})
|
|
81
|
-
}), /*#__PURE__*/_jsxs("div", {
|
|
82
|
-
children: [headerText && /*#__PURE__*/_jsx("h2", {
|
|
83
|
-
children: headerText
|
|
84
|
-
}), subHeaderText && /*#__PURE__*/_jsx("span", {
|
|
85
|
-
children: subHeaderText
|
|
86
|
-
})]
|
|
87
|
-
})]
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
}), tabbedNavigation && /*#__PURE__*/_jsx(TabbedNavigation, {
|
|
91
|
-
disableUpcoming: disableUpcomingInTabbedNavigation,
|
|
92
|
-
items: tabbedNavigation.filter(function (item) {
|
|
93
|
-
return !item.isHiddenInNav;
|
|
94
|
-
})
|
|
95
|
-
}), /*#__PURE__*/_jsx(HandoffMessage, {}), /*#__PURE__*/_jsxs("div", {
|
|
85
|
+
var tabbedNavigationRegion = tabbedNavigation && /*#__PURE__*/_jsx(TabbedNavigation, {
|
|
86
|
+
disableUpcoming: disableUpcomingInTabbedNavigation,
|
|
87
|
+
items: tabbedNavigation.filter(function (item) {
|
|
88
|
+
return !item.isHiddenInNav;
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
var content = /*#__PURE__*/_jsxs(_Fragment, {
|
|
92
|
+
children: [/*#__PURE__*/_jsx(HandoffMessage, {}), /*#__PURE__*/_jsxs("div", {
|
|
96
93
|
className: classnames('newspack-wizard newspack-wizard__content', className),
|
|
97
94
|
children: [typeof renderAboveContent === 'function' ? renderAboveContent() : null, /*#__PURE__*/_jsx(WrappedComponent, _objectSpread(_objectSpread({}, props), {}, {
|
|
98
95
|
renderPrimaryButton: renderPrimaryButton
|
|
@@ -106,6 +103,46 @@ export default function withWizardScreen(WrappedComponent) {
|
|
|
106
103
|
})]
|
|
107
104
|
})]
|
|
108
105
|
});
|
|
106
|
+
var renderPage = function renderPage(crumbs) {
|
|
107
|
+
var pageBreadcrumbs = crumbs !== null && crumbs !== void 0 ? crumbs : [];
|
|
108
|
+
if (!pageBreadcrumbs.length && headerText) {
|
|
109
|
+
pageBreadcrumbs = [{
|
|
110
|
+
label: headerText
|
|
111
|
+
}];
|
|
112
|
+
}
|
|
113
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
114
|
+
children: [newspack_aux_data.is_debug_mode && /*#__PURE__*/_jsx(Notice, {
|
|
115
|
+
debugMode: true
|
|
116
|
+
}), hideHeader ?
|
|
117
|
+
/*#__PURE__*/
|
|
118
|
+
// Without the Page shell the tabs still own the content: it
|
|
119
|
+
// renders inside the active tab's panel.
|
|
120
|
+
_jsx(_Fragment, {
|
|
121
|
+
children: tabbedNavigationRegion ? cloneElement(tabbedNavigationRegion, {
|
|
122
|
+
content: content
|
|
123
|
+
}) : content
|
|
124
|
+
}) : /*#__PURE__*/_jsx(Page, {
|
|
125
|
+
breadcrumbItems: pageBreadcrumbs,
|
|
126
|
+
subTitle: subHeaderText,
|
|
127
|
+
actions: headerActions,
|
|
128
|
+
tabbedNavigation: tabbedNavigationRegion,
|
|
129
|
+
children: content
|
|
130
|
+
})]
|
|
131
|
+
});
|
|
132
|
+
};
|
|
133
|
+
if (hideHeader) {
|
|
134
|
+
return renderPage();
|
|
135
|
+
}
|
|
136
|
+
if (breadcrumbItems) {
|
|
137
|
+
return renderPage(breadcrumbItems);
|
|
138
|
+
}
|
|
139
|
+
if (tabbedNavigation) {
|
|
140
|
+
return /*#__PURE__*/_jsx(RouteBreadcrumbs, {
|
|
141
|
+
sections: tabbedNavigation,
|
|
142
|
+
render: renderPage
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return renderPage();
|
|
109
146
|
};
|
|
110
147
|
return WrappedWithWizardScreen;
|
|
111
148
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies.
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { HashRouter } from 'react-router-dom';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies.
|
|
9
|
+
*/
|
|
10
|
+
import withWizardScreen from './';
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
global.newspack_aux_data = {
|
|
13
|
+
is_debug_mode: false
|
|
14
|
+
};
|
|
15
|
+
describe('withWizardScreen', function () {
|
|
16
|
+
it('falls back to a single headerText breadcrumb when no breadcrumbItems are provided', function () {
|
|
17
|
+
var WrappedComponent = function WrappedComponent() {
|
|
18
|
+
return /*#__PURE__*/_jsx("div", {
|
|
19
|
+
children: "Body content"
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
var ScreenWithHeader = withWizardScreen(WrappedComponent);
|
|
23
|
+
render(/*#__PURE__*/_jsx(HashRouter, {
|
|
24
|
+
children: /*#__PURE__*/_jsx(ScreenWithHeader, {
|
|
25
|
+
headerText: "Brands"
|
|
26
|
+
})
|
|
27
|
+
}));
|
|
28
|
+
expect(screen.getByRole('heading', {
|
|
29
|
+
level: 1
|
|
30
|
+
})).toHaveTextContent('Brands');
|
|
31
|
+
});
|
|
32
|
+
it('renders without a Router when no tabbed navigation is provided', function () {
|
|
33
|
+
var WrappedComponent = function WrappedComponent() {
|
|
34
|
+
return /*#__PURE__*/_jsx("div", {
|
|
35
|
+
children: "Body content"
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
var ScreenWithHeader = withWizardScreen(WrappedComponent);
|
|
39
|
+
render(/*#__PURE__*/_jsx(ScreenWithHeader, {
|
|
40
|
+
headerText: "Brands"
|
|
41
|
+
}));
|
|
42
|
+
expect(screen.getByRole('heading', {
|
|
43
|
+
level: 1
|
|
44
|
+
})).toHaveTextContent('Brands');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -45,129 +45,12 @@
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
&__header {
|
|
49
|
-
align-items: center;
|
|
50
|
-
background: white;
|
|
51
|
-
border-bottom: 1px solid wp-colors.$gray-300;
|
|
52
|
-
display: flex;
|
|
53
|
-
.newspack-wizard__fixed-header & {
|
|
54
|
-
position: sticky;
|
|
55
|
-
top: 0;
|
|
56
|
-
width: 100%;
|
|
57
|
-
z-index: 1000;
|
|
58
|
-
.admin-bar & {
|
|
59
|
-
@media only screen and ( min-width: 601px ) {
|
|
60
|
-
top: 46px;
|
|
61
|
-
}
|
|
62
|
-
@media only screen and ( min-width: 782px ) {
|
|
63
|
-
top: 32px;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
&__inner {
|
|
68
|
-
flex: 1 1 100%;
|
|
69
|
-
}
|
|
70
|
-
&__actions {
|
|
71
|
-
align-items: center;
|
|
72
|
-
display: flex;
|
|
73
|
-
gap: 8px;
|
|
74
|
-
justify-content: flex-end;
|
|
75
|
-
padding: 0 24px 0 0;
|
|
76
|
-
> .newspack-wizard__header__actions__main {
|
|
77
|
-
display: none;
|
|
78
|
-
}
|
|
79
|
-
@media only screen and ( min-width: 782px ) {
|
|
80
|
-
flex: 1 1 auto;
|
|
81
|
-
> .newspack-wizard__header__actions__main {
|
|
82
|
-
display: flex;
|
|
83
|
-
}
|
|
84
|
-
&__more {
|
|
85
|
-
&--primary-only,
|
|
86
|
-
.newspack-wizard__header__actions__more__main {
|
|
87
|
-
display: none;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
48
|
&__main {
|
|
95
|
-
overflow
|
|
49
|
+
overflow: hidden;
|
|
96
50
|
padding-bottom: 1px; /* Prevents borders from being cut off */
|
|
97
51
|
}
|
|
98
52
|
|
|
99
53
|
|
|
100
|
-
&__title {
|
|
101
|
-
align-items: center;
|
|
102
|
-
display: flex;
|
|
103
|
-
|
|
104
|
-
h2 {
|
|
105
|
-
margin: 0;
|
|
106
|
-
padding: 0;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
> div {
|
|
110
|
-
align-items: baseline;
|
|
111
|
-
display: flex;
|
|
112
|
-
padding: 0 24px;
|
|
113
|
-
|
|
114
|
-
> span {
|
|
115
|
-
color: wp-colors.$gray-700;
|
|
116
|
-
display: none;
|
|
117
|
-
margin-left: 8px;
|
|
118
|
-
|
|
119
|
-
@media screen and ( min-width: 744px ) {
|
|
120
|
-
display: block;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
svg {
|
|
126
|
-
fill: white;
|
|
127
|
-
margin: 0 !important;
|
|
128
|
-
|
|
129
|
-
&.newspack-icon {
|
|
130
|
-
flex: 0 0 36px;
|
|
131
|
-
margin-bottom: -1px !important;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
&:not(.newspack-icon) {
|
|
135
|
-
background: var(--wp-admin-theme-color);
|
|
136
|
-
left: 50%;
|
|
137
|
-
margin: -28px 0 0 -28px !important;
|
|
138
|
-
opacity: 0;
|
|
139
|
-
padding: 10px;
|
|
140
|
-
position: absolute;
|
|
141
|
-
top: 50%;
|
|
142
|
-
transition: opacity 125ms ease-in-out;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
.components-button.has-icon {
|
|
147
|
-
padding: 0;
|
|
148
|
-
position: relative;
|
|
149
|
-
|
|
150
|
-
&:hover {
|
|
151
|
-
svg {
|
|
152
|
-
opacity: 1;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
&:focus-visible {
|
|
157
|
-
outline: none !important;
|
|
158
|
-
|
|
159
|
-
&::before {
|
|
160
|
-
border: 2px solid white;
|
|
161
|
-
border-radius: 2px;
|
|
162
|
-
content: "";
|
|
163
|
-
display: block;
|
|
164
|
-
inset: 6px 6px 5px;
|
|
165
|
-
position: absolute;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
54
|
&__section-header {
|
|
172
55
|
margin: 0 auto 32px;
|
|
173
56
|
max-width: calc(calc(var(--newspack-wizard-section-space) * 2) + var(--newspack-wizard-section-width));
|
|
@@ -182,6 +65,7 @@
|
|
|
182
65
|
|
|
183
66
|
&__content {
|
|
184
67
|
margin: 0 auto;
|
|
68
|
+
width: 100%;
|
|
185
69
|
max-width: calc(calc(var(--newspack-wizard-section-space) * 2) + var(--newspack-wizard-section-width));
|
|
186
70
|
padding: calc(var(--newspack-wizard-section-space) * 2) var(--newspack-wizard-section-space) 0;
|
|
187
71
|
|
|
@@ -225,3 +109,16 @@
|
|
|
225
109
|
margin: 0;
|
|
226
110
|
}
|
|
227
111
|
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Wizard header overflow ("More") menu, rendered by the Wizard component into
|
|
115
|
+
* admin-ui's Page actions slot. Hide the toggle when there are no overflow
|
|
116
|
+
* actions, and hide the duplicated primary items inside the menu on wide
|
|
117
|
+
* viewports.
|
|
118
|
+
*/
|
|
119
|
+
@media only screen and ( min-width: 782px ) {
|
|
120
|
+
.newspack-wizard__actions__more--primary-only,
|
|
121
|
+
.newspack-wizard__actions__more .newspack-wizard__actions__more__main {
|
|
122
|
+
display: none;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
/**
|
|
3
|
+
* Internal dependencies.
|
|
4
|
+
*/
|
|
5
|
+
import { matchesRoute } from '../route-match';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Select the active section's explicit breadcrumb trail by current route. Falls
|
|
9
|
+
* back to the first section, then to an empty trail.
|
|
10
|
+
*
|
|
11
|
+
* @param {Array} sections Wizard sections (`{ path, breadcrumbs, exact?, activeTabPaths? }`).
|
|
12
|
+
* @param {string} pathname Current router pathname.
|
|
13
|
+
* @return {Array} Breadcrumb items `{ label, url? }`.
|
|
14
|
+
*/
|
|
15
|
+
export var activeBreadcrumbs = function activeBreadcrumbs() {
|
|
16
|
+
var sections = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
17
|
+
var pathname = arguments.length > 1 ? arguments[1] : undefined;
|
|
18
|
+
if (!(sections !== null && sections !== void 0 && sections.length)) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
var match = sections.find(function (section) {
|
|
22
|
+
return matchesRoute(section, pathname);
|
|
23
|
+
}) || sections[0];
|
|
24
|
+
return match.breadcrumbs || [];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Append a section's render-time current-page breadcrumb(s) to a trail.
|
|
29
|
+
*
|
|
30
|
+
* A section can supply a leaf via `headerData.sectionName` — either a single
|
|
31
|
+
* label (e.g. an integration name, or Add/Edit) or an ordered array of
|
|
32
|
+
* `{ label, url? }` crumbs when the leaf needs its own linked ancestors. Each
|
|
33
|
+
* crumb is appended in turn.
|
|
34
|
+
*
|
|
35
|
+
* Convention: a route authors its current-page leaf in exactly ONE place —
|
|
36
|
+
* the static `breadcrumbs` array for a constant label, or `sectionName` for a
|
|
37
|
+
* render-time label (e.g. Add/Edit) whose static trail then holds ancestors
|
|
38
|
+
* only. Never both. The trailing-label skip below is a defensive guard against
|
|
39
|
+
* a route accidentally doing both; it is not a supported pattern to rely on.
|
|
40
|
+
*
|
|
41
|
+
* @param {Array} breadcrumbItems Base trail `{ label, url? }[]`.
|
|
42
|
+
* @param {string|Array|undefined} sectionName A label, an array of crumbs, or falsy.
|
|
43
|
+
* @return {Array} A new trail with the section crumb(s) appended (deduped).
|
|
44
|
+
*/
|
|
45
|
+
export var appendSectionName = function appendSectionName() {
|
|
46
|
+
var breadcrumbItems = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
47
|
+
var sectionName = arguments.length > 1 ? arguments[1] : undefined;
|
|
48
|
+
if (!sectionName) {
|
|
49
|
+
return breadcrumbItems;
|
|
50
|
+
}
|
|
51
|
+
var extraCrumbs = (Array.isArray(sectionName) ? sectionName : [{
|
|
52
|
+
label: sectionName
|
|
53
|
+
}]).filter(function (crumb) {
|
|
54
|
+
return crumb === null || crumb === void 0 ? void 0 : crumb.label;
|
|
55
|
+
});
|
|
56
|
+
return extraCrumbs.reduce(function (trail, crumb) {
|
|
57
|
+
var _trail;
|
|
58
|
+
if (((_trail = trail[trail.length - 1]) === null || _trail === void 0 ? void 0 : _trail.label) === crumb.label) {
|
|
59
|
+
return trail;
|
|
60
|
+
}
|
|
61
|
+
return [].concat(_toConsumableArray(trail), [crumb]);
|
|
62
|
+
}, breadcrumbItems);
|
|
63
|
+
};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal dependencies.
|
|
3
|
+
*/
|
|
4
|
+
import { activeBreadcrumbs, appendSectionName } from './breadcrumbs-select';
|
|
5
|
+
var SECTIONS = [{
|
|
6
|
+
path: '/',
|
|
7
|
+
breadcrumbs: [{
|
|
8
|
+
label: 'Audience Management'
|
|
9
|
+
}, {
|
|
10
|
+
label: 'Configuration'
|
|
11
|
+
}]
|
|
12
|
+
}, {
|
|
13
|
+
path: '/donations',
|
|
14
|
+
breadcrumbs: [{
|
|
15
|
+
label: 'Audience Management'
|
|
16
|
+
}, {
|
|
17
|
+
label: 'Donations'
|
|
18
|
+
}]
|
|
19
|
+
}];
|
|
20
|
+
describe('activeBreadcrumbs', function () {
|
|
21
|
+
it('returns the matching section breadcrumbs by exact path', function () {
|
|
22
|
+
expect(activeBreadcrumbs(SECTIONS, '/donations')).toEqual([{
|
|
23
|
+
label: 'Audience Management'
|
|
24
|
+
}, {
|
|
25
|
+
label: 'Donations'
|
|
26
|
+
}]);
|
|
27
|
+
});
|
|
28
|
+
it('falls back to the first section when no path matches', function () {
|
|
29
|
+
expect(activeBreadcrumbs(SECTIONS, '/nope')).toEqual(SECTIONS[0].breadcrumbs);
|
|
30
|
+
});
|
|
31
|
+
it('returns [] when sections is empty', function () {
|
|
32
|
+
expect(activeBreadcrumbs([], '/x')).toEqual([]);
|
|
33
|
+
});
|
|
34
|
+
it('returns [] when sections is null or undefined', function () {
|
|
35
|
+
expect(activeBreadcrumbs(null, '/x')).toEqual([]);
|
|
36
|
+
expect(activeBreadcrumbs(undefined, '/x')).toEqual([]);
|
|
37
|
+
});
|
|
38
|
+
it('matches a non-exact section by path prefix', function () {
|
|
39
|
+
var sections = [{
|
|
40
|
+
path: '/',
|
|
41
|
+
breadcrumbs: [{
|
|
42
|
+
label: 'Root'
|
|
43
|
+
}]
|
|
44
|
+
}, {
|
|
45
|
+
path: '/access',
|
|
46
|
+
exact: false,
|
|
47
|
+
breadcrumbs: [{
|
|
48
|
+
label: 'Root'
|
|
49
|
+
}, {
|
|
50
|
+
label: 'Access control'
|
|
51
|
+
}]
|
|
52
|
+
}];
|
|
53
|
+
expect(activeBreadcrumbs(sections, '/access/institutions')).toEqual([{
|
|
54
|
+
label: 'Root'
|
|
55
|
+
}, {
|
|
56
|
+
label: 'Access control'
|
|
57
|
+
}]);
|
|
58
|
+
});
|
|
59
|
+
it('matches a parameterized route to its own breadcrumbs', function () {
|
|
60
|
+
var sections = [{
|
|
61
|
+
path: '/content-gates',
|
|
62
|
+
breadcrumbs: [{
|
|
63
|
+
label: 'Access control'
|
|
64
|
+
}]
|
|
65
|
+
}, {
|
|
66
|
+
path: '/institutions/:id',
|
|
67
|
+
exact: true,
|
|
68
|
+
breadcrumbs: [{
|
|
69
|
+
label: 'Access control'
|
|
70
|
+
}, {
|
|
71
|
+
label: 'Edit institution'
|
|
72
|
+
}]
|
|
73
|
+
}];
|
|
74
|
+
expect(activeBreadcrumbs(sections, '/institutions/123')).toEqual([{
|
|
75
|
+
label: 'Access control'
|
|
76
|
+
}, {
|
|
77
|
+
label: 'Edit institution'
|
|
78
|
+
}]);
|
|
79
|
+
});
|
|
80
|
+
it('matches via activeTabPaths wildcard', function () {
|
|
81
|
+
var sections = [{
|
|
82
|
+
path: '/',
|
|
83
|
+
breadcrumbs: [{
|
|
84
|
+
label: 'Root'
|
|
85
|
+
}]
|
|
86
|
+
}, {
|
|
87
|
+
path: '/segments',
|
|
88
|
+
activeTabPaths: ['/segments/*'],
|
|
89
|
+
breadcrumbs: [{
|
|
90
|
+
label: 'Root'
|
|
91
|
+
}, {
|
|
92
|
+
label: 'Segments'
|
|
93
|
+
}]
|
|
94
|
+
}];
|
|
95
|
+
expect(activeBreadcrumbs(sections, '/segments/123')).toEqual([{
|
|
96
|
+
label: 'Root'
|
|
97
|
+
}, {
|
|
98
|
+
label: 'Segments'
|
|
99
|
+
}]);
|
|
100
|
+
});
|
|
101
|
+
it('prefers an exact path match over the first section', function () {
|
|
102
|
+
expect(activeBreadcrumbs(SECTIONS, '/')).toEqual(SECTIONS[0].breadcrumbs);
|
|
103
|
+
});
|
|
104
|
+
it('returns [] when the matched section has no breadcrumbs', function () {
|
|
105
|
+
expect(activeBreadcrumbs([{
|
|
106
|
+
path: '/'
|
|
107
|
+
}], '/')).toEqual([]);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
describe('appendSectionName', function () {
|
|
111
|
+
var base = [{
|
|
112
|
+
label: 'Access Control'
|
|
113
|
+
}];
|
|
114
|
+
it('returns the base trail unchanged when sectionName is falsy', function () {
|
|
115
|
+
expect(appendSectionName(base, undefined)).toBe(base);
|
|
116
|
+
expect(appendSectionName(base, '')).toBe(base);
|
|
117
|
+
expect(appendSectionName(base, null)).toBe(base);
|
|
118
|
+
});
|
|
119
|
+
it('appends a string sectionName as a leaf crumb', function () {
|
|
120
|
+
expect(appendSectionName(base, 'Content Gifting')).toEqual([{
|
|
121
|
+
label: 'Access Control'
|
|
122
|
+
}, {
|
|
123
|
+
label: 'Content Gifting'
|
|
124
|
+
}]);
|
|
125
|
+
});
|
|
126
|
+
it('appends an array of crumbs in order', function () {
|
|
127
|
+
var sectionName = [{
|
|
128
|
+
label: 'Mailchimp',
|
|
129
|
+
url: '/mailchimp'
|
|
130
|
+
}, {
|
|
131
|
+
label: 'Logs'
|
|
132
|
+
}];
|
|
133
|
+
expect(appendSectionName(base, sectionName)).toEqual([{
|
|
134
|
+
label: 'Access Control'
|
|
135
|
+
}, {
|
|
136
|
+
label: 'Mailchimp',
|
|
137
|
+
url: '/mailchimp'
|
|
138
|
+
}, {
|
|
139
|
+
label: 'Logs'
|
|
140
|
+
}]);
|
|
141
|
+
});
|
|
142
|
+
it('dedupes a string leaf that repeats the current trailing label', function () {
|
|
143
|
+
var trail = [{
|
|
144
|
+
label: 'Access Control'
|
|
145
|
+
}, {
|
|
146
|
+
label: 'Metered Countdown'
|
|
147
|
+
}];
|
|
148
|
+
expect(appendSectionName(trail, 'Metered Countdown')).toEqual(trail);
|
|
149
|
+
});
|
|
150
|
+
it('dedupes an array leaf that repeats the current trailing label', function () {
|
|
151
|
+
var trail = [{
|
|
152
|
+
label: 'Access Control'
|
|
153
|
+
}, {
|
|
154
|
+
label: 'Metered Countdown'
|
|
155
|
+
}];
|
|
156
|
+
expect(appendSectionName(trail, [{
|
|
157
|
+
label: 'Metered Countdown'
|
|
158
|
+
}])).toEqual(trail);
|
|
159
|
+
});
|
|
160
|
+
it('skips crumbs without a label', function () {
|
|
161
|
+
expect(appendSectionName(base, [{
|
|
162
|
+
url: '/no-label'
|
|
163
|
+
}, {
|
|
164
|
+
label: 'Edit'
|
|
165
|
+
}])).toEqual([{
|
|
166
|
+
label: 'Access Control'
|
|
167
|
+
}, {
|
|
168
|
+
label: 'Edit'
|
|
169
|
+
}]);
|
|
170
|
+
});
|
|
171
|
+
it('only dedupes against the immediate predecessor, not earlier crumbs', function () {
|
|
172
|
+
var trail = [{
|
|
173
|
+
label: 'Access Control'
|
|
174
|
+
}, {
|
|
175
|
+
label: 'Institutions'
|
|
176
|
+
}];
|
|
177
|
+
// 'Access Control' repeats an earlier (non-adjacent) crumb, so it is kept.
|
|
178
|
+
expect(appendSectionName(trail, [{
|
|
179
|
+
label: 'Access Control'
|
|
180
|
+
}])).toEqual([{
|
|
181
|
+
label: 'Access Control'
|
|
182
|
+
}, {
|
|
183
|
+
label: 'Institutions'
|
|
184
|
+
}, {
|
|
185
|
+
label: 'Access Control'
|
|
186
|
+
}]);
|
|
187
|
+
});
|
|
188
|
+
it('does not mutate the input trail', function () {
|
|
189
|
+
var trail = [{
|
|
190
|
+
label: 'Access Control'
|
|
191
|
+
}];
|
|
192
|
+
appendSectionName(trail, 'Content Gifting');
|
|
193
|
+
expect(trail).toEqual([{
|
|
194
|
+
label: 'Access Control'
|
|
195
|
+
}]);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { __ } from '@wordpress/i18n';
|
|
5
5
|
import { useSelect } from '@wordpress/data';
|
|
6
|
+
import { __experimentalHStack as HStack } from '@wordpress/components'; // eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Internal dependencies.
|
|
9
10
|
*/
|
|
10
|
-
import { Button,
|
|
11
|
+
import { Button, Modal, Notice } from '../..';
|
|
11
12
|
import { WIZARD_STORE_NAMESPACE } from '../store';
|
|
12
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
14
|
var parseError = function parseError(_ref) {
|
|
@@ -46,10 +47,11 @@ var WizardError = function WizardError() {
|
|
|
46
47
|
noticeText: message,
|
|
47
48
|
isError: true,
|
|
48
49
|
rawHTML: true
|
|
49
|
-
}), fallbackURL && /*#__PURE__*/_jsx(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
}), fallbackURL && /*#__PURE__*/_jsx(HStack, {
|
|
51
|
+
justify: "flex-end",
|
|
52
|
+
spacing: 4,
|
|
53
|
+
wrap: true,
|
|
54
|
+
className: "newspack-modal__footer",
|
|
53
55
|
children: /*#__PURE__*/_jsx(Button, {
|
|
54
56
|
isPrimary: true,
|
|
55
57
|
href: fallbackURL,
|