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
package/dist/esm/wizard/index.js
CHANGED
|
@@ -12,19 +12,20 @@ import classnames from 'classnames';
|
|
|
12
12
|
*/
|
|
13
13
|
import { DropdownMenu, MenuGroup, MenuItem } from '@wordpress/components';
|
|
14
14
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
15
|
-
import { useEffect, useState, forwardRef } from '@wordpress/element';
|
|
15
|
+
import { cloneElement, isValidElement, useEffect, useState, forwardRef } from '@wordpress/element';
|
|
16
16
|
import { __ } from '@wordpress/i18n';
|
|
17
17
|
import { category, chevronLeft, moreVertical } from '@wordpress/icons';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Internal dependencies
|
|
21
21
|
*/
|
|
22
|
-
import { Footer, Notice, Button,
|
|
22
|
+
import { Footer, Notice, Button, TabbedNavigation, PluginInstaller, SectionHeader, HandoffMessage, Page } from '../';
|
|
23
|
+
import { activeBreadcrumbs, appendSectionName } from './breadcrumbs-select';
|
|
23
24
|
import Router from '../proxied-imports/router';
|
|
24
25
|
import registerStore, { WIZARD_STORE_NAMESPACE } from './store';
|
|
25
26
|
import WizardSnackbar from './components/WizardSnackbar';
|
|
26
27
|
import WizardError from './components/WizardError';
|
|
27
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
28
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
28
29
|
registerStore();
|
|
29
30
|
|
|
30
31
|
/**
|
|
@@ -63,6 +64,49 @@ var ResetHeaderData = function ResetHeaderData() {
|
|
|
63
64
|
return null;
|
|
64
65
|
};
|
|
65
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Wizard header + content region. Rendered inside the wizard's HashRouter so it
|
|
69
|
+
* can read the current route and derive the active-tab breadcrumb.
|
|
70
|
+
*/
|
|
71
|
+
var WizardHeaderRegion = function WizardHeaderRegion(_ref) {
|
|
72
|
+
var hideHeader = _ref.hideHeader,
|
|
73
|
+
headerText = _ref.headerText,
|
|
74
|
+
sections = _ref.sections,
|
|
75
|
+
sectionName = _ref.sectionName,
|
|
76
|
+
subTitle = _ref.subTitle,
|
|
77
|
+
actions = _ref.actions,
|
|
78
|
+
tabbedNavigation = _ref.tabbedNavigation,
|
|
79
|
+
children = _ref.children;
|
|
80
|
+
var _useLocation = useLocation(),
|
|
81
|
+
pathname = _useLocation.pathname;
|
|
82
|
+
if (hideHeader) {
|
|
83
|
+
// Without the Page shell the tabs still own the content: it renders
|
|
84
|
+
// inside the active tab's panel.
|
|
85
|
+
if (isValidElement(tabbedNavigation)) {
|
|
86
|
+
return cloneElement(tabbedNavigation, {
|
|
87
|
+
content: children
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return children;
|
|
91
|
+
}
|
|
92
|
+
var breadcrumbItems = activeBreadcrumbs(sections, pathname);
|
|
93
|
+
if (!breadcrumbItems.length && headerText) {
|
|
94
|
+
breadcrumbItems = [{
|
|
95
|
+
label: headerText
|
|
96
|
+
}];
|
|
97
|
+
}
|
|
98
|
+
// Append any render-time leaf crumb(s) the section supplied via
|
|
99
|
+
// headerData.sectionName (deduped against the current trailing label).
|
|
100
|
+
breadcrumbItems = appendSectionName(breadcrumbItems, sectionName);
|
|
101
|
+
return /*#__PURE__*/_jsx(Page, {
|
|
102
|
+
breadcrumbItems: breadcrumbItems,
|
|
103
|
+
subTitle: subTitle,
|
|
104
|
+
actions: actions,
|
|
105
|
+
tabbedNavigation: tabbedNavigation,
|
|
106
|
+
children: children
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
|
|
66
110
|
/**
|
|
67
111
|
* @typedef {Object} WizardProps
|
|
68
112
|
* @property {string} headerText The header text.
|
|
@@ -84,23 +128,23 @@ var ResetHeaderData = function ResetHeaderData() {
|
|
|
84
128
|
* @param {WizardProps} props
|
|
85
129
|
* @return {JSX.Element} Wizard component
|
|
86
130
|
*/
|
|
87
|
-
var Wizard = function Wizard(
|
|
88
|
-
var
|
|
89
|
-
sections =
|
|
90
|
-
headerText =
|
|
91
|
-
apiSlug =
|
|
92
|
-
|
|
93
|
-
sharedProps =
|
|
94
|
-
subHeaderText =
|
|
95
|
-
hasSimpleFooter =
|
|
96
|
-
className =
|
|
97
|
-
renderAboveSections =
|
|
98
|
-
|
|
99
|
-
requiredPlugins =
|
|
100
|
-
|
|
101
|
-
isInitialFetchTriggered =
|
|
102
|
-
|
|
103
|
-
|
|
131
|
+
var Wizard = function Wizard(_ref2, ref) {
|
|
132
|
+
var _ref2$sections = _ref2.sections,
|
|
133
|
+
sections = _ref2$sections === void 0 ? [] : _ref2$sections,
|
|
134
|
+
headerText = _ref2.headerText,
|
|
135
|
+
apiSlug = _ref2.apiSlug,
|
|
136
|
+
_ref2$sharedProps = _ref2.sharedProps,
|
|
137
|
+
sharedProps = _ref2$sharedProps === void 0 ? {} : _ref2$sharedProps,
|
|
138
|
+
subHeaderText = _ref2.subHeaderText,
|
|
139
|
+
hasSimpleFooter = _ref2.hasSimpleFooter,
|
|
140
|
+
className = _ref2.className,
|
|
141
|
+
renderAboveSections = _ref2.renderAboveSections,
|
|
142
|
+
_ref2$requiredPlugins = _ref2.requiredPlugins,
|
|
143
|
+
requiredPlugins = _ref2$requiredPlugins === void 0 ? [] : _ref2$requiredPlugins,
|
|
144
|
+
_ref2$isInitialFetchT = _ref2.isInitialFetchTriggered,
|
|
145
|
+
isInitialFetchTriggered = _ref2$isInitialFetchT === void 0 ? true : _ref2$isInitialFetchT,
|
|
146
|
+
_ref2$hideHeader = _ref2.hideHeader,
|
|
147
|
+
hideHeader = _ref2$hideHeader === void 0 ? false : _ref2$hideHeader;
|
|
104
148
|
var isLoading = useSelect(function (select) {
|
|
105
149
|
return select(WIZARD_STORE_NAMESPACE).isLoading();
|
|
106
150
|
});
|
|
@@ -148,8 +192,8 @@ var Wizard = function Wizard(_ref, ref) {
|
|
|
148
192
|
render: function render() {
|
|
149
193
|
return /*#__PURE__*/_jsx(PluginInstaller, {
|
|
150
194
|
plugins: requiredPlugins,
|
|
151
|
-
onStatus: function onStatus(
|
|
152
|
-
var complete =
|
|
195
|
+
onStatus: function onStatus(_ref3) {
|
|
196
|
+
var complete = _ref3.complete;
|
|
153
197
|
return setPluginRequirementsSatisfied(complete);
|
|
154
198
|
}
|
|
155
199
|
});
|
|
@@ -160,137 +204,114 @@ var Wizard = function Wizard(_ref, ref) {
|
|
|
160
204
|
// When plugins are required but not yet satisfied, `displayedSections` is replaced with
|
|
161
205
|
// the PluginInstaller. Use it for routing so the installer actually mounts and runs.
|
|
162
206
|
var routedSections = pluginRequirementsSatisfied ? sections : displayedSections;
|
|
163
|
-
var
|
|
207
|
+
var tabbedNavigation = displayedSections.length > 1 && /*#__PURE__*/_jsx(TabbedNavigation, {
|
|
208
|
+
items: displayedSections,
|
|
209
|
+
children: /*#__PURE__*/_jsx(WizardError, {})
|
|
210
|
+
});
|
|
211
|
+
var content = /*#__PURE__*/_jsxs(_Fragment, {
|
|
212
|
+
children: [/*#__PURE__*/_jsx(HandoffMessage, {}), sections.length > 1 && /*#__PURE__*/_jsx(ResetHeaderData, {}), /*#__PURE__*/_jsx("div", {
|
|
213
|
+
className: "newspack-wizard__main",
|
|
214
|
+
children: /*#__PURE__*/_jsxs(Switch, {
|
|
215
|
+
children: [routedSections.map(function (section, index) {
|
|
216
|
+
var _section$exact;
|
|
217
|
+
var SectionComponent = section.render;
|
|
218
|
+
var sectionProps = section.props || {};
|
|
219
|
+
return /*#__PURE__*/_jsx(Route, {
|
|
220
|
+
exact: (_section$exact = section.exact) !== null && _section$exact !== void 0 ? _section$exact : false,
|
|
221
|
+
path: section.path,
|
|
222
|
+
render: function render(routerProps) {
|
|
223
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
224
|
+
className: classnames('newspack-wizard__content', className, {
|
|
225
|
+
'newspack-wizard__content--full-width': section.fullWidth
|
|
226
|
+
}),
|
|
227
|
+
children: ['function' === typeof renderAboveSections ? renderAboveSections() : null, (sectionTitle || section.title) && /*#__PURE__*/_jsx(SectionHeader, {
|
|
228
|
+
className: "newspack-wizard__section-header",
|
|
229
|
+
backNav: backNav || section.backNav,
|
|
230
|
+
title: sectionTitle || section.title,
|
|
231
|
+
description: sectionDescription || section.description,
|
|
232
|
+
badges: badges || section.badges,
|
|
233
|
+
menu: sectionMenu || section.menu,
|
|
234
|
+
primaryAction: sectionPrimaryAction || section.primaryAction,
|
|
235
|
+
secondaryAction: sectionSecondaryAction || section.secondaryAction,
|
|
236
|
+
heading: 2,
|
|
237
|
+
noMargin: true
|
|
238
|
+
}), /*#__PURE__*/_jsx(SectionComponent, _objectSpread(_objectSpread(_objectSpread({}, routerProps), sectionProps), sharedProps))]
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}, index);
|
|
242
|
+
}), /*#__PURE__*/_jsx(Redirect, {
|
|
243
|
+
to: displayedSections[0].path
|
|
244
|
+
})]
|
|
245
|
+
})
|
|
246
|
+
})]
|
|
247
|
+
});
|
|
248
|
+
var headerActions = (actions === null || actions === void 0 ? void 0 : actions.length) > 0 ? /*#__PURE__*/_jsxs(_Fragment, {
|
|
249
|
+
children: [mainActions.map(function (action, index) {
|
|
250
|
+
return /*#__PURE__*/_jsx(Button, {
|
|
251
|
+
className: "newspack-wizard__actions__main",
|
|
252
|
+
href: action.href,
|
|
253
|
+
icon: resolveIcon(action.icon),
|
|
254
|
+
variant: action.type,
|
|
255
|
+
onClick: action.action,
|
|
256
|
+
disabled: action.disabled || false,
|
|
257
|
+
isDestructive: action.destructive || false,
|
|
258
|
+
children: action.label
|
|
259
|
+
}, index);
|
|
260
|
+
}), /*#__PURE__*/_jsx(DropdownMenu, {
|
|
261
|
+
className: (moreActions === null || moreActions === void 0 ? void 0 : moreActions.length) === 0 ? 'newspack-wizard__actions__more--primary-only' : '',
|
|
262
|
+
icon: moreVertical,
|
|
263
|
+
label: __('More', 'newspack-plugin'),
|
|
264
|
+
popoverProps: {
|
|
265
|
+
className: 'newspack-wizard__actions__more'
|
|
266
|
+
},
|
|
267
|
+
children: function children() {
|
|
268
|
+
return (
|
|
269
|
+
// Split actions into groups whenever an action opts in via `separator: true`.
|
|
270
|
+
// Consecutive MenuGroups render the WordPress-standard divider between them.
|
|
271
|
+
actions.reduce(function (groups, action) {
|
|
272
|
+
if (action.separator || groups.length === 0) {
|
|
273
|
+
groups.push([]);
|
|
274
|
+
}
|
|
275
|
+
groups[groups.length - 1].push(action);
|
|
276
|
+
return groups;
|
|
277
|
+
}, []).map(function (group, groupIndex) {
|
|
278
|
+
return /*#__PURE__*/_jsx(MenuGroup, {
|
|
279
|
+
children: group.map(function (action, index) {
|
|
280
|
+
return /*#__PURE__*/_jsx(MenuItem, {
|
|
281
|
+
className: action.type === 'primary' || action.type === 'secondary' ? 'newspack-wizard__actions__more__main' : 'newspack-wizard__actions__more__more',
|
|
282
|
+
icon: action.icon,
|
|
283
|
+
href: action.href,
|
|
284
|
+
onClick: action.action,
|
|
285
|
+
disabled: action.disabled || false,
|
|
286
|
+
isDestructive: action.destructive || false,
|
|
287
|
+
children: action.label
|
|
288
|
+
}, index);
|
|
289
|
+
})
|
|
290
|
+
}, groupIndex);
|
|
291
|
+
})
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
})]
|
|
295
|
+
}) : undefined;
|
|
164
296
|
return /*#__PURE__*/_jsxs("div", {
|
|
165
297
|
ref: ref,
|
|
166
298
|
children: [/*#__PURE__*/_jsxs("div", {
|
|
167
299
|
className: classnames(isLoading ? 'newspack-wizard__is-loading' : 'newspack-wizard__is-loaded', {
|
|
168
|
-
'newspack-wizard__is-loading-quiet': isQuietLoading
|
|
169
|
-
'newspack-wizard__fixed-header': fixedHeader
|
|
300
|
+
'newspack-wizard__is-loading-quiet': isQuietLoading
|
|
170
301
|
}),
|
|
171
302
|
children: [/*#__PURE__*/_jsxs(HashRouter, {
|
|
172
303
|
hashType: "slash",
|
|
173
304
|
children: [newspack_aux_data.is_debug_mode && /*#__PURE__*/_jsx(Notice, {
|
|
174
305
|
debugMode: true
|
|
175
|
-
}), /*#__PURE__*/
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
label: __('Return to Dashboard', 'newspack-plugin'),
|
|
185
|
-
showTooltip: true,
|
|
186
|
-
icon: category,
|
|
187
|
-
iconSize: 36,
|
|
188
|
-
children: /*#__PURE__*/_jsx(NewspackIcon, {
|
|
189
|
-
size: 36
|
|
190
|
-
})
|
|
191
|
-
}) : /*#__PURE__*/_jsx(NewspackIcon, {
|
|
192
|
-
size: 36
|
|
193
|
-
}), /*#__PURE__*/_jsxs("div", {
|
|
194
|
-
children: [headerText && /*#__PURE__*/_jsxs("h2", {
|
|
195
|
-
className: "newspack-wizard__header__title",
|
|
196
|
-
children: [headerText, sectionName && /*#__PURE__*/_jsxs("span", {
|
|
197
|
-
className: "newspack-wizard__header__section",
|
|
198
|
-
children: [/*#__PURE__*/_jsx("span", {
|
|
199
|
-
className: "newspack-wizard__header__section__separator",
|
|
200
|
-
children: " / "
|
|
201
|
-
}), " ", sectionName]
|
|
202
|
-
})]
|
|
203
|
-
}), subHeaderText && /*#__PURE__*/_jsx("span", {
|
|
204
|
-
children: subHeaderText
|
|
205
|
-
})]
|
|
206
|
-
})]
|
|
207
|
-
})
|
|
208
|
-
}), (actions === null || actions === void 0 ? void 0 : actions.length) > 0 && /*#__PURE__*/_jsxs("div", {
|
|
209
|
-
className: "newspack-wizard__header__actions",
|
|
210
|
-
children: [mainActions.map(function (action, index) {
|
|
211
|
-
return /*#__PURE__*/_jsx(Button, {
|
|
212
|
-
className: "newspack-wizard__header__actions__main",
|
|
213
|
-
href: action.href,
|
|
214
|
-
icon: resolveIcon(action.icon),
|
|
215
|
-
variant: action.type,
|
|
216
|
-
onClick: action.action,
|
|
217
|
-
disabled: action.disabled || false,
|
|
218
|
-
isDestructive: action.destructive || false,
|
|
219
|
-
children: action.label
|
|
220
|
-
}, index);
|
|
221
|
-
}), /*#__PURE__*/_jsx(DropdownMenu, {
|
|
222
|
-
className: (moreActions === null || moreActions === void 0 ? void 0 : moreActions.length) === 0 ? 'newspack-wizard__header__actions__more--primary-only' : '',
|
|
223
|
-
icon: moreVertical,
|
|
224
|
-
label: __('More', 'newspack-plugin'),
|
|
225
|
-
popoverProps: {
|
|
226
|
-
className: 'newspack-wizard__header__actions__more'
|
|
227
|
-
},
|
|
228
|
-
children: function children() {
|
|
229
|
-
return (
|
|
230
|
-
// Split actions into groups whenever an action opts in via `separator: true`.
|
|
231
|
-
// Consecutive MenuGroups render the WordPress-standard divider between them.
|
|
232
|
-
actions.reduce(function (groups, action) {
|
|
233
|
-
if (action.separator || groups.length === 0) {
|
|
234
|
-
groups.push([]);
|
|
235
|
-
}
|
|
236
|
-
groups[groups.length - 1].push(action);
|
|
237
|
-
return groups;
|
|
238
|
-
}, []).map(function (group, groupIndex) {
|
|
239
|
-
return /*#__PURE__*/_jsx(MenuGroup, {
|
|
240
|
-
children: group.map(function (action, index) {
|
|
241
|
-
return /*#__PURE__*/_jsx(MenuItem, {
|
|
242
|
-
className: action.type === 'primary' || action.type === 'secondary' ? 'newspack-wizard__header__actions__more__main' : 'newspack-wizard__header__actions__more__more',
|
|
243
|
-
icon: action.icon,
|
|
244
|
-
href: action.href,
|
|
245
|
-
onClick: action.action,
|
|
246
|
-
disabled: action.disabled || false,
|
|
247
|
-
isDestructive: action.destructive || false,
|
|
248
|
-
children: action.label
|
|
249
|
-
}, index);
|
|
250
|
-
})
|
|
251
|
-
}, groupIndex);
|
|
252
|
-
})
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
})]
|
|
256
|
-
})]
|
|
257
|
-
}), displayedSections.length > 1 && /*#__PURE__*/_jsx(TabbedNavigation, {
|
|
258
|
-
items: displayedSections,
|
|
259
|
-
children: /*#__PURE__*/_jsx(WizardError, {})
|
|
260
|
-
}), /*#__PURE__*/_jsx(HandoffMessage, {}), sections.length > 1 && /*#__PURE__*/_jsx(ResetHeaderData, {}), /*#__PURE__*/_jsx("div", {
|
|
261
|
-
className: "newspack-wizard__main",
|
|
262
|
-
children: /*#__PURE__*/_jsxs(Switch, {
|
|
263
|
-
children: [routedSections.map(function (section, index) {
|
|
264
|
-
var _section$exact;
|
|
265
|
-
var SectionComponent = section.render;
|
|
266
|
-
var sectionProps = section.props || {};
|
|
267
|
-
return /*#__PURE__*/_jsx(Route, {
|
|
268
|
-
exact: (_section$exact = section.exact) !== null && _section$exact !== void 0 ? _section$exact : false,
|
|
269
|
-
path: section.path,
|
|
270
|
-
render: function render(routerProps) {
|
|
271
|
-
return /*#__PURE__*/_jsxs("div", {
|
|
272
|
-
className: classnames('newspack-wizard__content', className, {
|
|
273
|
-
'newspack-wizard__content--full-width': section.fullWidth
|
|
274
|
-
}),
|
|
275
|
-
children: ['function' === typeof renderAboveSections ? renderAboveSections() : null, (sectionTitle || section.title) && /*#__PURE__*/_jsx(SectionHeader, {
|
|
276
|
-
className: "newspack-wizard__section-header",
|
|
277
|
-
backNav: backNav || section.backNav,
|
|
278
|
-
title: sectionTitle || section.title,
|
|
279
|
-
description: sectionDescription || section.description,
|
|
280
|
-
badges: badges || section.badges,
|
|
281
|
-
menu: sectionMenu || section.menu,
|
|
282
|
-
primaryAction: sectionPrimaryAction || section.primaryAction,
|
|
283
|
-
secondaryAction: sectionSecondaryAction || section.secondaryAction,
|
|
284
|
-
heading: 1,
|
|
285
|
-
noMargin: true
|
|
286
|
-
}), /*#__PURE__*/_jsx(SectionComponent, _objectSpread(_objectSpread(_objectSpread({}, routerProps), sectionProps), sharedProps))]
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
}, index);
|
|
290
|
-
}), /*#__PURE__*/_jsx(Redirect, {
|
|
291
|
-
to: displayedSections[0].path
|
|
292
|
-
})]
|
|
293
|
-
})
|
|
306
|
+
}), /*#__PURE__*/_jsx(WizardHeaderRegion, {
|
|
307
|
+
hideHeader: hideHeader,
|
|
308
|
+
headerText: headerText,
|
|
309
|
+
sections: routedSections,
|
|
310
|
+
sectionName: sectionName,
|
|
311
|
+
subTitle: subHeaderText,
|
|
312
|
+
actions: headerActions,
|
|
313
|
+
tabbedNavigation: tabbedNavigation,
|
|
314
|
+
children: content
|
|
294
315
|
})]
|
|
295
316
|
}), (notices === null || notices === void 0 ? void 0 : notices.length) > 0 && /*#__PURE__*/_jsx("div", {
|
|
296
317
|
className: "newspack-wizard__snackbar-list",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "newspack-components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.6.0",
|
|
4
4
|
"description": "Newspack design system components",
|
|
5
5
|
"author": "Automattic",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -23,9 +23,14 @@
|
|
|
23
23
|
"access": "public"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
+
"@wordpress/admin-ui": "2.4.0",
|
|
27
|
+
"@wordpress/style-runtime": "^0.5.0",
|
|
28
|
+
"@wordpress/theme": "^0.16.0",
|
|
29
|
+
"@wordpress/ui": "^0.16.0",
|
|
26
30
|
"classnames": "^2.3.1",
|
|
27
31
|
"lodash": "^4.17.21",
|
|
28
32
|
"moment-range": "^3.1.1",
|
|
33
|
+
"newspack-icons": "1.1.0",
|
|
29
34
|
"qs": "^6.15.2",
|
|
30
35
|
"react-router-dom": "^5.3.4",
|
|
31
36
|
"@babel/runtime": "^7.29.7",
|
|
@@ -53,6 +58,7 @@
|
|
|
53
58
|
"@babel/preset-env": "^7.29.7",
|
|
54
59
|
"@babel/preset-react": "^7.29.7",
|
|
55
60
|
"@babel/preset-typescript": "^7.29.7",
|
|
61
|
+
"newspack-scripts": "5.10.0",
|
|
56
62
|
"recursive-copy": "^2.0.0"
|
|
57
63
|
},
|
|
58
64
|
"babel": {
|
|
@@ -67,8 +73,10 @@
|
|
|
67
73
|
"compile:cjs": "babel src --config-file ./babel.config.cjs.js --extensions='.js,.jsx,.ts,.tsx' --out-dir dist/cjs",
|
|
68
74
|
"compile:esm": "babel src --extensions='.js,.jsx,.ts,.tsx' --out-dir dist/esm",
|
|
69
75
|
"compile": "npm run compile:cjs && npm run compile:esm",
|
|
76
|
+
"test": "newspack-scripts test",
|
|
70
77
|
"prepublishOnly": "npm run clean && npm run compile && node copy-styles.js",
|
|
71
78
|
"postpublish": "npm run clean",
|
|
72
|
-
"build": "npm run clean && npm run compile && node copy-styles.js"
|
|
79
|
+
"build": "npm run clean && npm run compile && node copy-styles.js",
|
|
80
|
+
"typescript:check": "newspack-scripts typescript-check"
|
|
73
81
|
}
|
|
74
82
|
}
|
package/src/accordion/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WordPress dependencies
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { __experimentalVStack as VStack, PanelBody } from '@wordpress/components'; // eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
5
|
+
import { Children, Fragment, cloneElement } from '@wordpress/element';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* External dependencies
|
|
@@ -12,22 +12,34 @@ import classNames from 'classnames';
|
|
|
12
12
|
/**
|
|
13
13
|
* Internal dependencies
|
|
14
14
|
*/
|
|
15
|
+
import Divider from '../divider';
|
|
15
16
|
import './style.scss';
|
|
16
17
|
|
|
17
|
-
const
|
|
18
|
-
|
|
18
|
+
export const AccordionPanel = ( { children, className, title, defaultOpen = false } ) => (
|
|
19
|
+
<PanelBody className={ className } title={ title } initialOpen={ defaultOpen }>
|
|
20
|
+
{ children }
|
|
21
|
+
</PanelBody>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const Accordion = ( { children, className, hideSingleTitle = false, spacing = 6 } ) => {
|
|
25
|
+
const panels = Children.toArray( children );
|
|
26
|
+
// With nothing to collapse against, a lone panel can render open and untitled.
|
|
27
|
+
if ( hideSingleTitle && panels.length === 1 ) {
|
|
28
|
+
return (
|
|
29
|
+
<div className={ classNames( 'newspack-accordion', className ) }>
|
|
30
|
+
{ cloneElement( panels[ 0 ], { defaultOpen: true, title: undefined } ) }
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
19
34
|
return (
|
|
20
|
-
<
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</summary>
|
|
29
|
-
<div className="newspack-accordion__content">{ children }</div>
|
|
30
|
-
</details>
|
|
35
|
+
<VStack className={ classNames( 'newspack-accordion', className ) } spacing={ spacing }>
|
|
36
|
+
{ panels.map( ( panel, index ) => (
|
|
37
|
+
<Fragment key={ panel.key }>
|
|
38
|
+
{ panel }
|
|
39
|
+
{ index < panels.length - 1 && <Divider variant="secondary" marginBottom={ 0 } marginTop={ 0 } /> }
|
|
40
|
+
</Fragment>
|
|
41
|
+
) ) }
|
|
42
|
+
</VStack>
|
|
31
43
|
);
|
|
32
44
|
};
|
|
33
45
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import Accordion, { AccordionPanel } from './index';
|
|
10
|
+
|
|
11
|
+
const renderPanels = ( count, props = {} ) =>
|
|
12
|
+
render(
|
|
13
|
+
<Accordion { ...props }>
|
|
14
|
+
{ Array.from( { length: count }, ( _, i ) => (
|
|
15
|
+
<AccordionPanel key={ i } title={ `Panel ${ i }` }>
|
|
16
|
+
content
|
|
17
|
+
</AccordionPanel>
|
|
18
|
+
) ) }
|
|
19
|
+
</Accordion>
|
|
20
|
+
);
|
|
21
|
+
|
|
22
|
+
const dividers = container => container.querySelectorAll( '.newspack-divider' );
|
|
23
|
+
|
|
24
|
+
describe( 'Accordion dividers', () => {
|
|
25
|
+
it( 'renders no divider for a single panel', () => {
|
|
26
|
+
const { container } = renderPanels( 1 );
|
|
27
|
+
expect( container.querySelectorAll( '.components-panel__body' ) ).toHaveLength( 1 );
|
|
28
|
+
expect( dividers( container ) ).toHaveLength( 0 );
|
|
29
|
+
} );
|
|
30
|
+
|
|
31
|
+
it( 'renders a divider between panels but not after the last', () => {
|
|
32
|
+
const { container } = renderPanels( 3 );
|
|
33
|
+
expect( container.querySelectorAll( '.components-panel__body' ) ).toHaveLength( 3 );
|
|
34
|
+
expect( dividers( container ) ).toHaveLength( 2 );
|
|
35
|
+
expect( container.querySelector( '.newspack-accordion' ).lastElementChild ).not.toHaveClass( 'newspack-divider' );
|
|
36
|
+
} );
|
|
37
|
+
|
|
38
|
+
it( 'renders secondary dividers', () => {
|
|
39
|
+
const { container } = renderPanels( 2 );
|
|
40
|
+
expect( dividers( container )[ 0 ] ).toHaveClass( 'newspack-divider--variant-secondary' );
|
|
41
|
+
} );
|
|
42
|
+
} );
|
|
43
|
+
|
|
44
|
+
describe( 'Accordion hideSingleTitle', () => {
|
|
45
|
+
it( 'keeps the title on a lone panel by default', () => {
|
|
46
|
+
renderPanels( 1 );
|
|
47
|
+
expect( screen.getByRole( 'button', { name: 'Panel 0' } ) ).toBeInTheDocument();
|
|
48
|
+
} );
|
|
49
|
+
|
|
50
|
+
it( 'drops the title and opens a lone panel when set', () => {
|
|
51
|
+
const { container } = renderPanels( 1, { hideSingleTitle: true } );
|
|
52
|
+
expect( screen.queryByRole( 'button', { name: 'Panel 0' } ) ).not.toBeInTheDocument();
|
|
53
|
+
expect( container.querySelector( '.components-panel__body' ) ).toHaveClass( 'is-opened' );
|
|
54
|
+
expect( screen.getByText( 'content' ) ).toBeInTheDocument();
|
|
55
|
+
} );
|
|
56
|
+
|
|
57
|
+
it( 'leaves titles alone when there is more than one panel', () => {
|
|
58
|
+
renderPanels( 2, { hideSingleTitle: true } );
|
|
59
|
+
expect( screen.getByRole( 'button', { name: 'Panel 0' } ) ).toBeInTheDocument();
|
|
60
|
+
expect( screen.getByRole( 'button', { name: 'Panel 1' } ) ).toBeInTheDocument();
|
|
61
|
+
} );
|
|
62
|
+
} );
|
package/src/accordion/style.scss
CHANGED
|
@@ -1,31 +1,35 @@
|
|
|
1
|
-
@use "~@wordpress/base-styles/
|
|
1
|
+
@use "~@wordpress/base-styles/mixins" as wp-mixins;
|
|
2
|
+
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
2
3
|
|
|
4
|
+
// Sit flush with the surrounding column: core insets panels horizontally, which
|
|
5
|
+
// would misalign them against the section they belong to.
|
|
3
6
|
.newspack-accordion {
|
|
4
|
-
|
|
7
|
+
.components-panel__body {
|
|
8
|
+
border: 0;
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
> .components-panel__body-title:hover {
|
|
11
|
+
background: none;
|
|
12
|
+
}
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
.components-panel__body.is-opened {
|
|
16
|
+
padding: 0;
|
|
17
|
+
|
|
18
|
+
> .components-panel__body-title {
|
|
19
|
+
margin: 0 0 wp-vars.$grid-unit-30;
|
|
16
20
|
}
|
|
17
21
|
}
|
|
18
|
-
summary {
|
|
19
|
-
padding: 16px 32px;
|
|
20
|
-
display: flex;
|
|
21
|
-
align-items: center;
|
|
22
|
-
justify-content: space-between;
|
|
23
|
-
cursor: pointer;
|
|
24
|
-
font-size: 14px;
|
|
25
|
-
font-weight: bold;
|
|
26
|
-
}
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
.components-panel__body-toggle.components-button {
|
|
24
|
+
@include wp-mixins.heading-large();
|
|
25
|
+
padding: 0;
|
|
26
|
+
|
|
27
|
+
.components-panel__arrow {
|
|
28
|
+
right: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&:focus:not(:focus-visible) {
|
|
32
|
+
box-shadow: none;
|
|
33
|
+
}
|
|
30
34
|
}
|
|
31
35
|
}
|
|
@@ -77,28 +77,6 @@
|
|
|
77
77
|
padding: 0 4px;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
&.mv0 {
|
|
81
|
-
border-left-color: wp-colors.$gray-300;
|
|
82
|
-
border-radius: 0;
|
|
83
|
-
border-right-color: wp-colors.$gray-300;
|
|
84
|
-
|
|
85
|
-
&:first-of-type {
|
|
86
|
-
border-top-color: wp-colors.$gray-300;
|
|
87
|
-
border-top-left-radius: 3px;
|
|
88
|
-
border-top-right-radius: 3px;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
&:last-of-type {
|
|
92
|
-
border-bottom-color: wp-colors.$gray-300;
|
|
93
|
-
border-bottom-left-radius: 3px;
|
|
94
|
-
border-bottom-right-radius: 3px;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
& + & {
|
|
98
|
-
margin-top: -1px;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
80
|
&.newspack-card__is-disabled,
|
|
103
81
|
&.newspack-card__is-primary,
|
|
104
82
|
&.newspack-card__is-secondary,
|