newspack-components 4.8.0 → 4.8.1-alpha.1
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 +9 -0
- package/DEVELOPMENT.md +18 -17
- package/dist/cjs/action-card/index.js +85 -18
- package/dist/cjs/action-card/index.test.js +192 -5
- package/dist/cjs/action-card/style.scss +3 -9
- package/dist/cjs/debug-badge/index.js +44 -0
- package/dist/cjs/debug-badge/index.test.js +50 -0
- package/dist/cjs/debug-badge/style.scss +26 -0
- package/dist/cjs/empty-state/index.test.js +37 -24
- package/dist/cjs/empty-state/root.js +2 -1
- package/dist/cjs/footer/index.js +52 -16
- package/dist/cjs/footer/index.test.js +208 -0
- package/dist/cjs/footer/style.scss +17 -1
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/notice/index.js +1 -4
- package/dist/cjs/notice/style.scss +0 -19
- package/dist/cjs/plugin-toggle/index.js +1 -1
- package/dist/cjs/with-wizard-screen/index.js +1 -3
- package/dist/cjs/with-wizard-screen/index.test.js +0 -3
- package/dist/cjs/wizard/index.js +8 -7
- package/dist/cjs/wizard/index.test.js +158 -5
- package/dist/cjs/wizard/store/index.js +2 -0
- package/dist/esm/action-card/index.js +86 -21
- package/dist/esm/action-card/index.test.js +192 -1
- package/dist/esm/action-card/style.scss +3 -9
- package/dist/esm/debug-badge/index.js +39 -0
- package/dist/esm/debug-badge/index.test.js +46 -0
- package/dist/esm/debug-badge/style.scss +26 -0
- package/dist/esm/empty-state/index.test.js +37 -24
- package/dist/esm/empty-state/root.js +2 -1
- package/dist/esm/footer/index.js +52 -17
- package/dist/esm/footer/index.test.js +210 -0
- package/dist/esm/footer/style.scss +17 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/notice/index.js +2 -5
- package/dist/esm/notice/style.scss +0 -19
- package/dist/esm/plugin-toggle/index.js +1 -1
- package/dist/esm/with-wizard-screen/index.js +2 -4
- package/dist/esm/with-wizard-screen/index.test.js +0 -3
- package/dist/esm/wizard/index.js +11 -10
- package/dist/esm/wizard/index.test.js +158 -5
- package/dist/esm/wizard/store/index.js +2 -0
- package/package.json +1 -1
- package/src/action-card/action-card.d.ts +3 -2
- package/src/action-card/index.js +81 -8
- package/src/action-card/index.test.js +159 -0
- package/src/action-card/style.scss +3 -9
- package/src/debug-badge/index.js +36 -0
- package/src/debug-badge/index.test.js +39 -0
- package/src/debug-badge/style.scss +26 -0
- package/src/empty-state/README.md +11 -10
- package/src/empty-state/index.test.js +10 -0
- package/src/empty-state/root.tsx +2 -1
- package/src/empty-state/types.ts +1 -1
- package/src/footer/index.js +47 -2
- package/src/footer/index.test.js +114 -0
- package/src/footer/style.scss +17 -1
- package/src/index.js +1 -0
- package/src/notice/index.js +2 -17
- package/src/notice/style.scss +0 -19
- package/src/plugin-toggle/index.js +1 -1
- package/src/with-wizard-screen/index.js +2 -2
- package/src/with-wizard-screen/index.test.js +0 -2
- package/src/wizard/index.js +11 -9
- package/src/wizard/index.test.js +96 -3
- package/src/wizard/store/index.js +2 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug Badge
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* WordPress dependencies.
|
|
7
|
+
*/
|
|
8
|
+
import { __ } from '@wordpress/i18n';
|
|
9
|
+
import { Icon, bug } from '@wordpress/icons';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies.
|
|
13
|
+
*/
|
|
14
|
+
import './style.scss';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Debug Badge component.
|
|
18
|
+
*
|
|
19
|
+
* Gates itself on `window.newspack_aux_data.is_debug_mode`, so consumers render
|
|
20
|
+
* it unconditionally and it stays absent outside debug mode.
|
|
21
|
+
*
|
|
22
|
+
* @return {JSX.Element|null} Debug Badge component, or nothing outside debug mode.
|
|
23
|
+
*/
|
|
24
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
25
|
+
var DebugBadge = function DebugBadge() {
|
|
26
|
+
var _window$newspack_aux_;
|
|
27
|
+
if (!((_window$newspack_aux_ = window.newspack_aux_data) !== null && _window$newspack_aux_ !== void 0 && _window$newspack_aux_.is_debug_mode)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return /*#__PURE__*/_jsx("div", {
|
|
31
|
+
className: "newspack-debug-badge",
|
|
32
|
+
role: "img",
|
|
33
|
+
"aria-label": __('Debug mode', 'newspack-plugin'),
|
|
34
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
35
|
+
icon: bug
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
export default DebugBadge;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import DebugBadge from '.';
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
describe('DebugBadge', function () {
|
|
12
|
+
afterEach(function () {
|
|
13
|
+
delete window.newspack_aux_data;
|
|
14
|
+
});
|
|
15
|
+
it('renders the badge and its glyph in debug mode', function () {
|
|
16
|
+
window.newspack_aux_data = {
|
|
17
|
+
is_debug_mode: true
|
|
18
|
+
};
|
|
19
|
+
var _render = render(/*#__PURE__*/_jsx(DebugBadge, {})),
|
|
20
|
+
container = _render.container;
|
|
21
|
+
expect(container.querySelector('.newspack-debug-badge')).toBeInTheDocument();
|
|
22
|
+
expect(container.querySelector('.newspack-debug-badge > svg')).toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
it('names itself for assistive tech', function () {
|
|
25
|
+
window.newspack_aux_data = {
|
|
26
|
+
is_debug_mode: true
|
|
27
|
+
};
|
|
28
|
+
render(/*#__PURE__*/_jsx(DebugBadge, {}));
|
|
29
|
+
expect(screen.getByRole('img', {
|
|
30
|
+
name: 'Debug mode'
|
|
31
|
+
})).toBeInTheDocument();
|
|
32
|
+
});
|
|
33
|
+
it('renders nothing outside debug mode', function () {
|
|
34
|
+
window.newspack_aux_data = {
|
|
35
|
+
is_debug_mode: false
|
|
36
|
+
};
|
|
37
|
+
var _render2 = render(/*#__PURE__*/_jsx(DebugBadge, {})),
|
|
38
|
+
container = _render2.container;
|
|
39
|
+
expect(container).toBeEmptyDOMElement();
|
|
40
|
+
});
|
|
41
|
+
it('renders nothing when the global is absent', function () {
|
|
42
|
+
var _render3 = render(/*#__PURE__*/_jsx(DebugBadge, {})),
|
|
43
|
+
container = _render3.container;
|
|
44
|
+
expect(container).toBeEmptyDOMElement();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug Badge
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
6
|
+
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
7
|
+
@use "../../../colors/colors.module" as np-colors;
|
|
8
|
+
|
|
9
|
+
.newspack-debug-badge {
|
|
10
|
+
background: np-colors.$primary-600;
|
|
11
|
+
border-radius: wp-vars.$radius-round;
|
|
12
|
+
bottom: 0;
|
|
13
|
+
box-shadow: var(--wpds-elevation-sm, #{wp-vars.$elevation-small});
|
|
14
|
+
display: grid;
|
|
15
|
+
height: wp-vars.$button-size;
|
|
16
|
+
margin: 0 wp-vars.$grid-unit-30 wp-vars.$grid-unit-30;
|
|
17
|
+
place-items: center;
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
position: fixed;
|
|
20
|
+
width: wp-vars.$button-size;
|
|
21
|
+
z-index: 9997;
|
|
22
|
+
|
|
23
|
+
> svg {
|
|
24
|
+
fill: wp-colors.$white;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -49,17 +49,30 @@ describe('EmptyState.Root', function () {
|
|
|
49
49
|
gap: 'var(--wpds-dimension-gap-2xl, 32px)'
|
|
50
50
|
});
|
|
51
51
|
});
|
|
52
|
+
it('tightens the stack gap when small', function () {
|
|
53
|
+
var _render4 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
54
|
+
size: "small",
|
|
55
|
+
children: /*#__PURE__*/_jsx("p", {
|
|
56
|
+
children: "body"
|
|
57
|
+
})
|
|
58
|
+
})),
|
|
59
|
+
container = _render4.container;
|
|
60
|
+
var stack = container.querySelector('.newspack-empty-state').firstElementChild;
|
|
61
|
+
expect(stack).toHaveStyle({
|
|
62
|
+
gap: 'var(--wpds-dimension-gap-xl, 24px)'
|
|
63
|
+
});
|
|
64
|
+
});
|
|
52
65
|
|
|
53
66
|
// Consumers key `:has()` selectors off this class, so losing it changes their
|
|
54
67
|
// layout without failing anything.
|
|
55
68
|
it('merges className onto the grid', function () {
|
|
56
|
-
var
|
|
69
|
+
var _render5 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
57
70
|
className: "consumer-empty-state",
|
|
58
71
|
children: /*#__PURE__*/_jsx("p", {
|
|
59
72
|
children: "body"
|
|
60
73
|
})
|
|
61
74
|
})),
|
|
62
|
-
container =
|
|
75
|
+
container = _render5.container;
|
|
63
76
|
expect(container.querySelector('.newspack-empty-state')).toHaveClass('consumer-empty-state');
|
|
64
77
|
});
|
|
65
78
|
|
|
@@ -76,13 +89,13 @@ describe('EmptyState.Root', function () {
|
|
|
76
89
|
});
|
|
77
90
|
describe('EmptyState.Header', function () {
|
|
78
91
|
it('renders the title and description in the header', function () {
|
|
79
|
-
var
|
|
92
|
+
var _render6 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
80
93
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
81
94
|
title: "Get started with newsletters",
|
|
82
95
|
description: "Compose and send."
|
|
83
96
|
})
|
|
84
97
|
})),
|
|
85
|
-
container =
|
|
98
|
+
container = _render6.container;
|
|
86
99
|
expect(container.querySelector('.newspack-empty-state__title')).toHaveTextContent('Get started with newsletters');
|
|
87
100
|
expect(container.querySelector('.newspack-empty-state__description')).toHaveTextContent('Compose and send.');
|
|
88
101
|
});
|
|
@@ -90,13 +103,13 @@ describe('EmptyState.Header', function () {
|
|
|
90
103
|
// Spacing comes from the stacks, so a margin creeping back onto the heading or
|
|
91
104
|
// paragraph would silently widen every gap.
|
|
92
105
|
it('spaces the header from its stacks rather than from margins', function () {
|
|
93
|
-
var
|
|
106
|
+
var _render7 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
94
107
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
95
108
|
title: "Get started with newsletters",
|
|
96
109
|
description: "Compose and send."
|
|
97
110
|
})
|
|
98
111
|
})),
|
|
99
|
-
container =
|
|
112
|
+
container = _render7.container;
|
|
100
113
|
var header = container.querySelector('.newspack-empty-state__header');
|
|
101
114
|
expect(header).toHaveStyle({
|
|
102
115
|
flexDirection: 'column',
|
|
@@ -110,33 +123,33 @@ describe('EmptyState.Header', function () {
|
|
|
110
123
|
});
|
|
111
124
|
});
|
|
112
125
|
it('wraps the icon in the disc', function () {
|
|
113
|
-
var
|
|
126
|
+
var _render8 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
114
127
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
115
128
|
title: "Get started with newsletters",
|
|
116
129
|
icon: /*#__PURE__*/_jsx("svg", {})
|
|
117
130
|
})
|
|
118
131
|
})),
|
|
119
|
-
container =
|
|
132
|
+
container = _render8.container;
|
|
120
133
|
expect(container.querySelector('.newspack-empty-state__icon svg')).toBeInTheDocument();
|
|
121
134
|
});
|
|
122
135
|
it('omits the description and the icon when they are not given', function () {
|
|
123
|
-
var
|
|
136
|
+
var _render9 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
124
137
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
125
138
|
title: "Get started with newsletters"
|
|
126
139
|
})
|
|
127
140
|
})),
|
|
128
|
-
container =
|
|
141
|
+
container = _render9.container;
|
|
129
142
|
expect(container.querySelector('.newspack-empty-state__description')).not.toBeInTheDocument();
|
|
130
143
|
expect(container.querySelector('.newspack-empty-state__icon')).not.toBeInTheDocument();
|
|
131
144
|
});
|
|
132
145
|
it('renders an h2 and a 48px icon at the default size', function () {
|
|
133
|
-
var
|
|
146
|
+
var _render0 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
134
147
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
135
148
|
title: "Get started with newsletters",
|
|
136
149
|
icon: /*#__PURE__*/_jsx("svg", {})
|
|
137
150
|
})
|
|
138
151
|
})),
|
|
139
|
-
container =
|
|
152
|
+
container = _render0.container;
|
|
140
153
|
expect(screen.getByRole('heading', {
|
|
141
154
|
level: 2,
|
|
142
155
|
name: 'Get started with newsletters'
|
|
@@ -145,14 +158,14 @@ describe('EmptyState.Header', function () {
|
|
|
145
158
|
expect(container.querySelector('.newspack-empty-state__icon svg')).toHaveAttribute('width', '48');
|
|
146
159
|
});
|
|
147
160
|
it('drops to an h3, the small modifier and a 24px icon when the root is small', function () {
|
|
148
|
-
var
|
|
161
|
+
var _render1 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
149
162
|
size: "small",
|
|
150
163
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
151
164
|
title: "No products match this rule",
|
|
152
165
|
icon: /*#__PURE__*/_jsx("svg", {})
|
|
153
166
|
})
|
|
154
167
|
})),
|
|
155
|
-
container =
|
|
168
|
+
container = _render1.container;
|
|
156
169
|
expect(container.querySelector('.newspack-empty-state__header--small')).toBeInTheDocument();
|
|
157
170
|
expect(screen.getByRole('heading', {
|
|
158
171
|
level: 3,
|
|
@@ -177,13 +190,13 @@ describe('EmptyState.Header', function () {
|
|
|
177
190
|
})).toBeInTheDocument();
|
|
178
191
|
});
|
|
179
192
|
it('carries its own class hook alongside any className', function () {
|
|
180
|
-
var
|
|
193
|
+
var _render10 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
181
194
|
children: /*#__PURE__*/_jsx(EmptyState.Header, {
|
|
182
195
|
title: "Get started with newsletters",
|
|
183
196
|
className: "consumer-header"
|
|
184
197
|
})
|
|
185
198
|
})),
|
|
186
|
-
container =
|
|
199
|
+
container = _render10.container;
|
|
187
200
|
var header = container.querySelector('.newspack-empty-state__header');
|
|
188
201
|
expect(header).toBeInTheDocument();
|
|
189
202
|
expect(header).toHaveClass('consumer-header');
|
|
@@ -207,11 +220,11 @@ describe('EmptyState.Header', function () {
|
|
|
207
220
|
var previous = process.env.NODE_ENV;
|
|
208
221
|
process.env.NODE_ENV = 'production';
|
|
209
222
|
try {
|
|
210
|
-
var
|
|
223
|
+
var _render11 = render(/*#__PURE__*/_jsx(EmptyState.Header, {
|
|
211
224
|
title: "Orphan",
|
|
212
225
|
icon: /*#__PURE__*/_jsx("svg", {})
|
|
213
226
|
})),
|
|
214
|
-
container =
|
|
227
|
+
container = _render11.container;
|
|
215
228
|
expect(screen.getByRole('heading', {
|
|
216
229
|
level: 2,
|
|
217
230
|
name: 'Orphan'
|
|
@@ -225,7 +238,7 @@ describe('EmptyState.Header', function () {
|
|
|
225
238
|
});
|
|
226
239
|
describe('EmptyState.Actions', function () {
|
|
227
240
|
it('renders its children in a centred row', function () {
|
|
228
|
-
var
|
|
241
|
+
var _render12 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
229
242
|
children: /*#__PURE__*/_jsx(EmptyState.Actions, {
|
|
230
243
|
children: /*#__PURE__*/_jsx("button", {
|
|
231
244
|
type: "button",
|
|
@@ -233,7 +246,7 @@ describe('EmptyState.Actions', function () {
|
|
|
233
246
|
})
|
|
234
247
|
})
|
|
235
248
|
})),
|
|
236
|
-
container =
|
|
249
|
+
container = _render12.container;
|
|
237
250
|
expect(container.querySelector('.newspack-empty-state__actions')).toBeInTheDocument();
|
|
238
251
|
expect(container.querySelector('.newspack-empty-state__actions')).toHaveStyle({
|
|
239
252
|
justifyContent: 'center',
|
|
@@ -244,7 +257,7 @@ describe('EmptyState.Actions', function () {
|
|
|
244
257
|
})).toBeInTheDocument();
|
|
245
258
|
});
|
|
246
259
|
it('stacks into a column while keeping the hook class', function () {
|
|
247
|
-
var
|
|
260
|
+
var _render13 = render(/*#__PURE__*/_jsx(EmptyState.Root, {
|
|
248
261
|
children: /*#__PURE__*/_jsxs(EmptyState.Actions, {
|
|
249
262
|
orientation: "column",
|
|
250
263
|
children: [/*#__PURE__*/_jsx("button", {
|
|
@@ -256,7 +269,7 @@ describe('EmptyState.Actions', function () {
|
|
|
256
269
|
})]
|
|
257
270
|
})
|
|
258
271
|
})),
|
|
259
|
-
container =
|
|
272
|
+
container = _render13.container;
|
|
260
273
|
var actions = container.querySelector('.newspack-empty-state__actions');
|
|
261
274
|
expect(actions).toBeInTheDocument();
|
|
262
275
|
expect(actions).toHaveStyle({
|
|
@@ -287,10 +300,10 @@ describe('EmptyState.Actions', function () {
|
|
|
287
300
|
var previous = process.env.NODE_ENV;
|
|
288
301
|
process.env.NODE_ENV = 'production';
|
|
289
302
|
try {
|
|
290
|
-
var
|
|
303
|
+
var _render14 = render(/*#__PURE__*/_jsx(EmptyState.Actions, {
|
|
291
304
|
children: "x"
|
|
292
305
|
})),
|
|
293
|
-
container =
|
|
306
|
+
container = _render14.container;
|
|
294
307
|
expect(container.querySelector('.newspack-empty-state__actions')).toBeInTheDocument();
|
|
295
308
|
} finally {
|
|
296
309
|
process.env.NODE_ENV = previous;
|
|
@@ -37,6 +37,7 @@ var Root = function Root(_ref) {
|
|
|
37
37
|
size: size
|
|
38
38
|
};
|
|
39
39
|
}, [size]);
|
|
40
|
+
var isSmall = size === 'small';
|
|
40
41
|
return /*#__PURE__*/_jsx(EmptyStateContext.Provider, {
|
|
41
42
|
value: context,
|
|
42
43
|
children: /*#__PURE__*/_jsx(Grid, {
|
|
@@ -46,7 +47,7 @@ var Root = function Root(_ref) {
|
|
|
46
47
|
children: /*#__PURE__*/_jsx(Stack, _objectSpread(_objectSpread({
|
|
47
48
|
className: "newspack-empty-state__stack",
|
|
48
49
|
direction: "column",
|
|
49
|
-
gap:
|
|
50
|
+
gap: isSmall ? 'xl' : '2xl'
|
|
50
51
|
}, gridColumn), {}, {
|
|
51
52
|
children: children
|
|
52
53
|
}))
|
package/dist/esm/footer/index.js
CHANGED
|
@@ -11,8 +11,9 @@ import { ExternalLink } from '@wordpress/components';
|
|
|
11
11
|
/**
|
|
12
12
|
* Internal dependencies.
|
|
13
13
|
*/
|
|
14
|
+
import useConfirmDialog from '../hooks/use-confirm-dialog';
|
|
14
15
|
import './style.scss';
|
|
15
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
17
|
var Footer = function Footer(_ref) {
|
|
17
18
|
var _ref$simple = _ref.simple,
|
|
18
19
|
simple = _ref$simple === void 0 ? undefined : _ref$simple;
|
|
@@ -32,6 +33,18 @@ var Footer = function Footer(_ref) {
|
|
|
32
33
|
_ref2$remove_starter_ = _ref2.remove_starter_content,
|
|
33
34
|
removeStarterContent = _ref2$remove_starter_ === void 0 ? false : _ref2$remove_starter_,
|
|
34
35
|
supportEmail = _ref2.support_email;
|
|
36
|
+
var resetDialog = useConfirmDialog({
|
|
37
|
+
title: __('Reset Newspack?', 'newspack-plugin'),
|
|
38
|
+
message: __('This deletes the Newspack settings on this site and returns you to the setup wizard. Your posts, pages and users are not affected. This cannot be undone.', 'newspack-plugin'),
|
|
39
|
+
confirmButtonText: __('Reset Newspack', 'newspack-plugin'),
|
|
40
|
+
isDestructive: true
|
|
41
|
+
});
|
|
42
|
+
var starterContentDialog = useConfirmDialog({
|
|
43
|
+
title: __('Remove Starter Content?', 'newspack-plugin'),
|
|
44
|
+
message: __('This deletes the posts, pages and categories created as starter content. This cannot be undone.', 'newspack-plugin'),
|
|
45
|
+
confirmButtonText: __('Remove Starter Content', 'newspack-plugin'),
|
|
46
|
+
isDestructive: true
|
|
47
|
+
});
|
|
35
48
|
var footerElements = [{
|
|
36
49
|
label: pluginVersion.label,
|
|
37
50
|
url: 'https://newspack.com/category/release-notes/',
|
|
@@ -60,13 +73,15 @@ var Footer = function Footer(_ref) {
|
|
|
60
73
|
if (resetUrl) {
|
|
61
74
|
footerElements.push({
|
|
62
75
|
label: __('Reset Newspack', 'newspack-plugin'),
|
|
63
|
-
url: resetUrl
|
|
76
|
+
url: resetUrl,
|
|
77
|
+
confirm: resetDialog.requestConfirm
|
|
64
78
|
});
|
|
65
79
|
}
|
|
66
80
|
if (removeStarterContent) {
|
|
67
81
|
footerElements.push({
|
|
68
82
|
label: __('Remove Starter Content', 'newspack-plugin'),
|
|
69
|
-
url: removeStarterContent
|
|
83
|
+
url: removeStarterContent,
|
|
84
|
+
confirm: starterContentDialog.requestConfirm
|
|
70
85
|
});
|
|
71
86
|
}
|
|
72
87
|
if (supportEmail) {
|
|
@@ -75,24 +90,44 @@ var Footer = function Footer(_ref) {
|
|
|
75
90
|
url: "mailto:".concat(supportEmail)
|
|
76
91
|
});
|
|
77
92
|
}
|
|
78
|
-
|
|
93
|
+
var renderItem = function renderItem(_ref3) {
|
|
94
|
+
var url = _ref3.url,
|
|
95
|
+
label = _ref3.label,
|
|
96
|
+
external = _ref3.external,
|
|
97
|
+
confirm = _ref3.confirm;
|
|
98
|
+
if (external) {
|
|
99
|
+
return /*#__PURE__*/_jsx(ExternalLink, {
|
|
100
|
+
href: url,
|
|
101
|
+
children: label
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
if (!confirm) {
|
|
105
|
+
return /*#__PURE__*/_jsx("a", {
|
|
106
|
+
href: url,
|
|
107
|
+
children: label
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
// onClick only sees primary clicks, so an href here would let a middle-click
|
|
111
|
+
// or "Open link in new tab" reach the URL unguarded.
|
|
112
|
+
return /*#__PURE__*/_jsx("button", {
|
|
113
|
+
type: "button",
|
|
114
|
+
onClick: function onClick() {
|
|
115
|
+
return confirm(function () {
|
|
116
|
+
window.location.href = url;
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
children: label
|
|
120
|
+
});
|
|
121
|
+
};
|
|
122
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
79
123
|
className: "newspack-footer",
|
|
80
|
-
children: !simple && /*#__PURE__*/_jsx("ul", {
|
|
81
|
-
children: footerElements.map(function (
|
|
82
|
-
var url = _ref3.url,
|
|
83
|
-
label = _ref3.label,
|
|
84
|
-
external = _ref3.external;
|
|
124
|
+
children: [!simple && /*#__PURE__*/_jsx("ul", {
|
|
125
|
+
children: footerElements.map(function (element, index) {
|
|
85
126
|
return /*#__PURE__*/_jsx("li", {
|
|
86
|
-
children:
|
|
87
|
-
href: url,
|
|
88
|
-
children: label
|
|
89
|
-
}) : /*#__PURE__*/_jsx("a", {
|
|
90
|
-
href: url,
|
|
91
|
-
children: label
|
|
92
|
-
})
|
|
127
|
+
children: renderItem(element)
|
|
93
128
|
}, index);
|
|
94
129
|
})
|
|
95
|
-
})
|
|
130
|
+
}), resetDialog.confirmDialog, starterContentDialog.confirmDialog]
|
|
96
131
|
});
|
|
97
132
|
};
|
|
98
133
|
export default Footer;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
|
|
3
|
+
function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
|
|
4
|
+
/**
|
|
5
|
+
* External dependencies.
|
|
6
|
+
*/
|
|
7
|
+
import { fireEvent, render, screen, within } from '@testing-library/react';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Internal dependencies.
|
|
11
|
+
*/
|
|
12
|
+
import Footer from './';
|
|
13
|
+
|
|
14
|
+
// Footer renders outside the wizard's HashRouter, so there is no MemoryRouter
|
|
15
|
+
// wrapper here on purpose.
|
|
16
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
+
describe('Footer', function () {
|
|
18
|
+
var RESET_URL = 'https://example.test/wp-admin/admin.php?page=newspack-dashboard&newspack_reset=reset';
|
|
19
|
+
var STARTER_CONTENT_URL = 'https://example.test/wp-admin/admin.php?page=newspack-dashboard&newspack_reset=starter-content';
|
|
20
|
+
var assigned;
|
|
21
|
+
var originalLocation;
|
|
22
|
+
var originalUrls;
|
|
23
|
+
var confirmIn = /*#__PURE__*/function () {
|
|
24
|
+
var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(name) {
|
|
25
|
+
var _t;
|
|
26
|
+
return _regenerator().w(function (_context) {
|
|
27
|
+
while (1) switch (_context.n) {
|
|
28
|
+
case 0:
|
|
29
|
+
_t = within;
|
|
30
|
+
_context.n = 1;
|
|
31
|
+
return screen.findByRole('dialog');
|
|
32
|
+
case 1:
|
|
33
|
+
return _context.a(2, _t(_context.v).getByRole('button', {
|
|
34
|
+
name: name
|
|
35
|
+
}));
|
|
36
|
+
}
|
|
37
|
+
}, _callee);
|
|
38
|
+
}));
|
|
39
|
+
return function confirmIn(_x) {
|
|
40
|
+
return _ref.apply(this, arguments);
|
|
41
|
+
};
|
|
42
|
+
}();
|
|
43
|
+
beforeEach(function () {
|
|
44
|
+
assigned = [];
|
|
45
|
+
originalLocation = window.location;
|
|
46
|
+
originalUrls = window.newspack_urls;
|
|
47
|
+
delete window.location;
|
|
48
|
+
window.location = {
|
|
49
|
+
get href() {
|
|
50
|
+
return 'https://example.test/wp-admin/admin.php?page=newspack-dashboard';
|
|
51
|
+
},
|
|
52
|
+
set href(value) {
|
|
53
|
+
assigned.push(value);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
window.newspack_urls = {
|
|
57
|
+
support: 'https://help.newspack.com/',
|
|
58
|
+
reset_url: RESET_URL,
|
|
59
|
+
remove_starter_content: STARTER_CONTENT_URL,
|
|
60
|
+
plugin_version: {
|
|
61
|
+
label: 'Newspack 1.0.0'
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
afterEach(function () {
|
|
66
|
+
delete window.location;
|
|
67
|
+
window.location = originalLocation;
|
|
68
|
+
if (undefined === originalUrls) {
|
|
69
|
+
delete window.newspack_urls;
|
|
70
|
+
} else {
|
|
71
|
+
window.newspack_urls = originalUrls;
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
it('offers no link for a browser gesture to follow', function () {
|
|
75
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
76
|
+
expect(screen.getByRole('button', {
|
|
77
|
+
name: 'Reset Newspack'
|
|
78
|
+
})).not.toHaveAttribute('href');
|
|
79
|
+
expect(screen.getByRole('button', {
|
|
80
|
+
name: 'Remove Starter Content'
|
|
81
|
+
})).not.toHaveAttribute('href');
|
|
82
|
+
});
|
|
83
|
+
it('does not reset on the first click', function () {
|
|
84
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
85
|
+
fireEvent.click(screen.getByRole('button', {
|
|
86
|
+
name: 'Reset Newspack'
|
|
87
|
+
}));
|
|
88
|
+
expect(assigned).toEqual([]);
|
|
89
|
+
});
|
|
90
|
+
it('asks before resetting', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
91
|
+
var _t2;
|
|
92
|
+
return _regenerator().w(function (_context2) {
|
|
93
|
+
while (1) switch (_context2.n) {
|
|
94
|
+
case 0:
|
|
95
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
96
|
+
fireEvent.click(screen.getByRole('button', {
|
|
97
|
+
name: 'Reset Newspack'
|
|
98
|
+
}));
|
|
99
|
+
_t2 = expect;
|
|
100
|
+
_context2.n = 1;
|
|
101
|
+
return screen.findByText(/deletes the Newspack settings/);
|
|
102
|
+
case 1:
|
|
103
|
+
_t2(_context2.v).toBeInTheDocument();
|
|
104
|
+
case 2:
|
|
105
|
+
return _context2.a(2);
|
|
106
|
+
}
|
|
107
|
+
}, _callee2);
|
|
108
|
+
})));
|
|
109
|
+
it('leaves the site alone when the reset is cancelled', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
110
|
+
var cancel;
|
|
111
|
+
return _regenerator().w(function (_context3) {
|
|
112
|
+
while (1) switch (_context3.n) {
|
|
113
|
+
case 0:
|
|
114
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
115
|
+
fireEvent.click(screen.getByRole('button', {
|
|
116
|
+
name: 'Reset Newspack'
|
|
117
|
+
}));
|
|
118
|
+
// The modal's close icon also carries aria-label="Cancel"; this is the text button.
|
|
119
|
+
_context3.n = 1;
|
|
120
|
+
return screen.findAllByRole('button', {
|
|
121
|
+
name: 'Cancel'
|
|
122
|
+
});
|
|
123
|
+
case 1:
|
|
124
|
+
cancel = _context3.v.find(function (button) {
|
|
125
|
+
return 'Cancel' === button.textContent;
|
|
126
|
+
});
|
|
127
|
+
fireEvent.click(cancel);
|
|
128
|
+
expect(assigned).toEqual([]);
|
|
129
|
+
case 2:
|
|
130
|
+
return _context3.a(2);
|
|
131
|
+
}
|
|
132
|
+
}, _callee3);
|
|
133
|
+
})));
|
|
134
|
+
it('resets once confirmed', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4() {
|
|
135
|
+
var _t3;
|
|
136
|
+
return _regenerator().w(function (_context4) {
|
|
137
|
+
while (1) switch (_context4.n) {
|
|
138
|
+
case 0:
|
|
139
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
140
|
+
fireEvent.click(screen.getByRole('button', {
|
|
141
|
+
name: 'Reset Newspack'
|
|
142
|
+
}));
|
|
143
|
+
_t3 = fireEvent;
|
|
144
|
+
_context4.n = 1;
|
|
145
|
+
return confirmIn('Reset Newspack');
|
|
146
|
+
case 1:
|
|
147
|
+
_t3.click.call(_t3, _context4.v);
|
|
148
|
+
expect(assigned).toEqual([RESET_URL]);
|
|
149
|
+
case 2:
|
|
150
|
+
return _context4.a(2);
|
|
151
|
+
}
|
|
152
|
+
}, _callee4);
|
|
153
|
+
})));
|
|
154
|
+
it('does not remove the starter content on the first click', function () {
|
|
155
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
156
|
+
fireEvent.click(screen.getByRole('button', {
|
|
157
|
+
name: 'Remove Starter Content'
|
|
158
|
+
}));
|
|
159
|
+
expect(assigned).toEqual([]);
|
|
160
|
+
});
|
|
161
|
+
it('asks before removing the starter content', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5() {
|
|
162
|
+
var _t4;
|
|
163
|
+
return _regenerator().w(function (_context5) {
|
|
164
|
+
while (1) switch (_context5.n) {
|
|
165
|
+
case 0:
|
|
166
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
167
|
+
fireEvent.click(screen.getByRole('button', {
|
|
168
|
+
name: 'Remove Starter Content'
|
|
169
|
+
}));
|
|
170
|
+
_t4 = expect;
|
|
171
|
+
_context5.n = 1;
|
|
172
|
+
return screen.findByText(/created as starter content/);
|
|
173
|
+
case 1:
|
|
174
|
+
_t4(_context5.v).toBeInTheDocument();
|
|
175
|
+
case 2:
|
|
176
|
+
return _context5.a(2);
|
|
177
|
+
}
|
|
178
|
+
}, _callee5);
|
|
179
|
+
})));
|
|
180
|
+
it('removes the starter content once confirmed', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
181
|
+
var _t5;
|
|
182
|
+
return _regenerator().w(function (_context6) {
|
|
183
|
+
while (1) switch (_context6.n) {
|
|
184
|
+
case 0:
|
|
185
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
186
|
+
fireEvent.click(screen.getByRole('button', {
|
|
187
|
+
name: 'Remove Starter Content'
|
|
188
|
+
}));
|
|
189
|
+
_t5 = fireEvent;
|
|
190
|
+
_context6.n = 1;
|
|
191
|
+
return confirmIn('Remove Starter Content');
|
|
192
|
+
case 1:
|
|
193
|
+
_t5.click.call(_t5, _context6.v);
|
|
194
|
+
expect(assigned).toEqual([STARTER_CONTENT_URL]);
|
|
195
|
+
case 2:
|
|
196
|
+
return _context6.a(2);
|
|
197
|
+
}
|
|
198
|
+
}, _callee6);
|
|
199
|
+
})));
|
|
200
|
+
it('does not guard the non-destructive links', function () {
|
|
201
|
+
window.newspack_urls.setup_wizard = 'https://example.test/wp-admin/admin.php?page=newspack-setup-wizard';
|
|
202
|
+
render(/*#__PURE__*/_jsx(Footer, {}));
|
|
203
|
+
var link = screen.getByRole('link', {
|
|
204
|
+
name: 'Setup Wizard'
|
|
205
|
+
});
|
|
206
|
+
expect(link).toHaveAttribute('href', window.newspack_urls.setup_wizard);
|
|
207
|
+
fireEvent.click(link);
|
|
208
|
+
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
209
|
+
});
|
|
210
|
+
});
|