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.
Files changed (66) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/DEVELOPMENT.md +18 -17
  3. package/dist/cjs/action-card/index.js +85 -18
  4. package/dist/cjs/action-card/index.test.js +192 -5
  5. package/dist/cjs/action-card/style.scss +3 -9
  6. package/dist/cjs/debug-badge/index.js +44 -0
  7. package/dist/cjs/debug-badge/index.test.js +50 -0
  8. package/dist/cjs/debug-badge/style.scss +26 -0
  9. package/dist/cjs/empty-state/index.test.js +37 -24
  10. package/dist/cjs/empty-state/root.js +2 -1
  11. package/dist/cjs/footer/index.js +52 -16
  12. package/dist/cjs/footer/index.test.js +208 -0
  13. package/dist/cjs/footer/style.scss +17 -1
  14. package/dist/cjs/index.js +7 -0
  15. package/dist/cjs/notice/index.js +1 -4
  16. package/dist/cjs/notice/style.scss +0 -19
  17. package/dist/cjs/plugin-toggle/index.js +1 -1
  18. package/dist/cjs/with-wizard-screen/index.js +1 -3
  19. package/dist/cjs/with-wizard-screen/index.test.js +0 -3
  20. package/dist/cjs/wizard/index.js +8 -7
  21. package/dist/cjs/wizard/index.test.js +158 -5
  22. package/dist/cjs/wizard/store/index.js +2 -0
  23. package/dist/esm/action-card/index.js +86 -21
  24. package/dist/esm/action-card/index.test.js +192 -1
  25. package/dist/esm/action-card/style.scss +3 -9
  26. package/dist/esm/debug-badge/index.js +39 -0
  27. package/dist/esm/debug-badge/index.test.js +46 -0
  28. package/dist/esm/debug-badge/style.scss +26 -0
  29. package/dist/esm/empty-state/index.test.js +37 -24
  30. package/dist/esm/empty-state/root.js +2 -1
  31. package/dist/esm/footer/index.js +52 -17
  32. package/dist/esm/footer/index.test.js +210 -0
  33. package/dist/esm/footer/style.scss +17 -1
  34. package/dist/esm/index.js +1 -0
  35. package/dist/esm/notice/index.js +2 -5
  36. package/dist/esm/notice/style.scss +0 -19
  37. package/dist/esm/plugin-toggle/index.js +1 -1
  38. package/dist/esm/with-wizard-screen/index.js +2 -4
  39. package/dist/esm/with-wizard-screen/index.test.js +0 -3
  40. package/dist/esm/wizard/index.js +11 -10
  41. package/dist/esm/wizard/index.test.js +158 -5
  42. package/dist/esm/wizard/store/index.js +2 -0
  43. package/package.json +1 -1
  44. package/src/action-card/action-card.d.ts +3 -2
  45. package/src/action-card/index.js +81 -8
  46. package/src/action-card/index.test.js +159 -0
  47. package/src/action-card/style.scss +3 -9
  48. package/src/debug-badge/index.js +36 -0
  49. package/src/debug-badge/index.test.js +39 -0
  50. package/src/debug-badge/style.scss +26 -0
  51. package/src/empty-state/README.md +11 -10
  52. package/src/empty-state/index.test.js +10 -0
  53. package/src/empty-state/root.tsx +2 -1
  54. package/src/empty-state/types.ts +1 -1
  55. package/src/footer/index.js +47 -2
  56. package/src/footer/index.test.js +114 -0
  57. package/src/footer/style.scss +17 -1
  58. package/src/index.js +1 -0
  59. package/src/notice/index.js +2 -17
  60. package/src/notice/style.scss +0 -19
  61. package/src/plugin-toggle/index.js +1 -1
  62. package/src/with-wizard-screen/index.js +2 -2
  63. package/src/with-wizard-screen/index.test.js +0 -2
  64. package/src/wizard/index.js +11 -9
  65. package/src/wizard/index.test.js +96 -3
  66. package/src/wizard/store/index.js +2 -0
@@ -53,17 +53,30 @@ describe('EmptyState.Root', function () {
53
53
  gap: 'var(--wpds-dimension-gap-2xl, 32px)'
54
54
  });
55
55
  });
56
+ it('tightens the stack gap when small', function () {
57
+ var _render4 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
58
+ size: "small",
59
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
60
+ children: "body"
61
+ })
62
+ })),
63
+ container = _render4.container;
64
+ var stack = container.querySelector('.newspack-empty-state').firstElementChild;
65
+ expect(stack).toHaveStyle({
66
+ gap: 'var(--wpds-dimension-gap-xl, 24px)'
67
+ });
68
+ });
56
69
 
57
70
  // Consumers key `:has()` selectors off this class, so losing it changes their
58
71
  // layout without failing anything.
59
72
  it('merges className onto the grid', function () {
60
- var _render4 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
73
+ var _render5 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
61
74
  className: "consumer-empty-state",
62
75
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
63
76
  children: "body"
64
77
  })
65
78
  })),
66
- container = _render4.container;
79
+ container = _render5.container;
67
80
  expect(container.querySelector('.newspack-empty-state')).toHaveClass('consumer-empty-state');
68
81
  });
69
82
 
@@ -80,13 +93,13 @@ describe('EmptyState.Root', function () {
80
93
  });
81
94
  describe('EmptyState.Header', function () {
82
95
  it('renders the title and description in the header', function () {
83
- var _render5 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
96
+ var _render6 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
84
97
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
85
98
  title: "Get started with newsletters",
86
99
  description: "Compose and send."
87
100
  })
88
101
  })),
89
- container = _render5.container;
102
+ container = _render6.container;
90
103
  expect(container.querySelector('.newspack-empty-state__title')).toHaveTextContent('Get started with newsletters');
91
104
  expect(container.querySelector('.newspack-empty-state__description')).toHaveTextContent('Compose and send.');
92
105
  });
@@ -94,13 +107,13 @@ describe('EmptyState.Header', function () {
94
107
  // Spacing comes from the stacks, so a margin creeping back onto the heading or
95
108
  // paragraph would silently widen every gap.
96
109
  it('spaces the header from its stacks rather than from margins', function () {
97
- var _render6 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
110
+ var _render7 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
98
111
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
99
112
  title: "Get started with newsletters",
100
113
  description: "Compose and send."
101
114
  })
102
115
  })),
103
- container = _render6.container;
116
+ container = _render7.container;
104
117
  var header = container.querySelector('.newspack-empty-state__header');
105
118
  expect(header).toHaveStyle({
106
119
  flexDirection: 'column',
@@ -114,33 +127,33 @@ describe('EmptyState.Header', function () {
114
127
  });
115
128
  });
116
129
  it('wraps the icon in the disc', function () {
117
- var _render7 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
130
+ var _render8 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
118
131
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
119
132
  title: "Get started with newsletters",
120
133
  icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
121
134
  })
122
135
  })),
123
- container = _render7.container;
136
+ container = _render8.container;
124
137
  expect(container.querySelector('.newspack-empty-state__icon svg')).toBeInTheDocument();
125
138
  });
126
139
  it('omits the description and the icon when they are not given', function () {
127
- var _render8 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
140
+ var _render9 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
128
141
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
129
142
  title: "Get started with newsletters"
130
143
  })
131
144
  })),
132
- container = _render8.container;
145
+ container = _render9.container;
133
146
  expect(container.querySelector('.newspack-empty-state__description')).not.toBeInTheDocument();
134
147
  expect(container.querySelector('.newspack-empty-state__icon')).not.toBeInTheDocument();
135
148
  });
136
149
  it('renders an h2 and a 48px icon at the default size', function () {
137
- var _render9 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
150
+ var _render0 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
138
151
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
139
152
  title: "Get started with newsletters",
140
153
  icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
141
154
  })
142
155
  })),
143
- container = _render9.container;
156
+ container = _render0.container;
144
157
  expect(_react.screen.getByRole('heading', {
145
158
  level: 2,
146
159
  name: 'Get started with newsletters'
@@ -149,14 +162,14 @@ describe('EmptyState.Header', function () {
149
162
  expect(container.querySelector('.newspack-empty-state__icon svg')).toHaveAttribute('width', '48');
150
163
  });
151
164
  it('drops to an h3, the small modifier and a 24px icon when the root is small', function () {
152
- var _render0 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
165
+ var _render1 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
153
166
  size: "small",
154
167
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
155
168
  title: "No products match this rule",
156
169
  icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
157
170
  })
158
171
  })),
159
- container = _render0.container;
172
+ container = _render1.container;
160
173
  expect(container.querySelector('.newspack-empty-state__header--small')).toBeInTheDocument();
161
174
  expect(_react.screen.getByRole('heading', {
162
175
  level: 3,
@@ -181,13 +194,13 @@ describe('EmptyState.Header', function () {
181
194
  })).toBeInTheDocument();
182
195
  });
183
196
  it('carries its own class hook alongside any className', function () {
184
- var _render1 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
197
+ var _render10 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
185
198
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
186
199
  title: "Get started with newsletters",
187
200
  className: "consumer-header"
188
201
  })
189
202
  })),
190
- container = _render1.container;
203
+ container = _render10.container;
191
204
  var header = container.querySelector('.newspack-empty-state__header');
192
205
  expect(header).toBeInTheDocument();
193
206
  expect(header).toHaveClass('consumer-header');
@@ -211,11 +224,11 @@ describe('EmptyState.Header', function () {
211
224
  var previous = process.env.NODE_ENV;
212
225
  process.env.NODE_ENV = 'production';
213
226
  try {
214
- var _render10 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
227
+ var _render11 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
215
228
  title: "Orphan",
216
229
  icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
217
230
  })),
218
- container = _render10.container;
231
+ container = _render11.container;
219
232
  expect(_react.screen.getByRole('heading', {
220
233
  level: 2,
221
234
  name: 'Orphan'
@@ -229,7 +242,7 @@ describe('EmptyState.Header', function () {
229
242
  });
230
243
  describe('EmptyState.Actions', function () {
231
244
  it('renders its children in a centred row', function () {
232
- var _render11 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
245
+ var _render12 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
233
246
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Actions, {
234
247
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
235
248
  type: "button",
@@ -237,7 +250,7 @@ describe('EmptyState.Actions', function () {
237
250
  })
238
251
  })
239
252
  })),
240
- container = _render11.container;
253
+ container = _render12.container;
241
254
  expect(container.querySelector('.newspack-empty-state__actions')).toBeInTheDocument();
242
255
  expect(container.querySelector('.newspack-empty-state__actions')).toHaveStyle({
243
256
  justifyContent: 'center',
@@ -248,7 +261,7 @@ describe('EmptyState.Actions', function () {
248
261
  })).toBeInTheDocument();
249
262
  });
250
263
  it('stacks into a column while keeping the hook class', function () {
251
- var _render12 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
264
+ var _render13 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
252
265
  children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_["default"].Actions, {
253
266
  orientation: "column",
254
267
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
@@ -260,7 +273,7 @@ describe('EmptyState.Actions', function () {
260
273
  })]
261
274
  })
262
275
  })),
263
- container = _render12.container;
276
+ container = _render13.container;
264
277
  var actions = container.querySelector('.newspack-empty-state__actions');
265
278
  expect(actions).toBeInTheDocument();
266
279
  expect(actions).toHaveStyle({
@@ -291,10 +304,10 @@ describe('EmptyState.Actions', function () {
291
304
  var previous = process.env.NODE_ENV;
292
305
  process.env.NODE_ENV = 'production';
293
306
  try {
294
- var _render13 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Actions, {
307
+ var _render14 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Actions, {
295
308
  children: "x"
296
309
  })),
297
- container = _render13.container;
310
+ container = _render14.container;
298
311
  expect(container.querySelector('.newspack-empty-state__actions')).toBeInTheDocument();
299
312
  } finally {
300
313
  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__*/(0, _jsxRuntime.jsx)(_context.EmptyStateContext.Provider, {
41
42
  value: context,
42
43
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_grid["default"], {
@@ -46,7 +47,7 @@ var Root = function Root(_ref) {
46
47
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Stack, _objectSpread(_objectSpread({
47
48
  className: "newspack-empty-state__stack",
48
49
  direction: "column",
49
- gap: "2xl"
50
+ gap: isSmall ? 'xl' : '2xl'
50
51
  }, gridColumn), {}, {
51
52
  children: children
52
53
  }))
@@ -1,11 +1,13 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports["default"] = void 0;
7
8
  var _i18n = require("@wordpress/i18n");
8
9
  var _components = require("@wordpress/components");
10
+ var _useConfirmDialog = _interopRequireDefault(require("../hooks/use-confirm-dialog"));
9
11
  require("./style.scss");
10
12
  var _jsxRuntime = require("react/jsx-runtime");
11
13
  /**
@@ -39,6 +41,18 @@ var Footer = function Footer(_ref) {
39
41
  _ref2$remove_starter_ = _ref2.remove_starter_content,
40
42
  removeStarterContent = _ref2$remove_starter_ === void 0 ? false : _ref2$remove_starter_,
41
43
  supportEmail = _ref2.support_email;
44
+ var resetDialog = (0, _useConfirmDialog["default"])({
45
+ title: (0, _i18n.__)('Reset Newspack?', 'newspack-plugin'),
46
+ message: (0, _i18n.__)('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'),
47
+ confirmButtonText: (0, _i18n.__)('Reset Newspack', 'newspack-plugin'),
48
+ isDestructive: true
49
+ });
50
+ var starterContentDialog = (0, _useConfirmDialog["default"])({
51
+ title: (0, _i18n.__)('Remove Starter Content?', 'newspack-plugin'),
52
+ message: (0, _i18n.__)('This deletes the posts, pages and categories created as starter content. This cannot be undone.', 'newspack-plugin'),
53
+ confirmButtonText: (0, _i18n.__)('Remove Starter Content', 'newspack-plugin'),
54
+ isDestructive: true
55
+ });
42
56
  var footerElements = [{
43
57
  label: pluginVersion.label,
44
58
  url: 'https://newspack.com/category/release-notes/',
@@ -67,13 +81,15 @@ var Footer = function Footer(_ref) {
67
81
  if (resetUrl) {
68
82
  footerElements.push({
69
83
  label: (0, _i18n.__)('Reset Newspack', 'newspack-plugin'),
70
- url: resetUrl
84
+ url: resetUrl,
85
+ confirm: resetDialog.requestConfirm
71
86
  });
72
87
  }
73
88
  if (removeStarterContent) {
74
89
  footerElements.push({
75
90
  label: (0, _i18n.__)('Remove Starter Content', 'newspack-plugin'),
76
- url: removeStarterContent
91
+ url: removeStarterContent,
92
+ confirm: starterContentDialog.requestConfirm
77
93
  });
78
94
  }
79
95
  if (supportEmail) {
@@ -82,24 +98,44 @@ var Footer = function Footer(_ref) {
82
98
  url: "mailto:".concat(supportEmail)
83
99
  });
84
100
  }
85
- return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
101
+ var renderItem = function renderItem(_ref3) {
102
+ var url = _ref3.url,
103
+ label = _ref3.label,
104
+ external = _ref3.external,
105
+ confirm = _ref3.confirm;
106
+ if (external) {
107
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ExternalLink, {
108
+ href: url,
109
+ children: label
110
+ });
111
+ }
112
+ if (!confirm) {
113
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
114
+ href: url,
115
+ children: label
116
+ });
117
+ }
118
+ // onClick only sees primary clicks, so an href here would let a middle-click
119
+ // or "Open link in new tab" reach the URL unguarded.
120
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
121
+ type: "button",
122
+ onClick: function onClick() {
123
+ return confirm(function () {
124
+ window.location.href = url;
125
+ });
126
+ },
127
+ children: label
128
+ });
129
+ };
130
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
86
131
  className: "newspack-footer",
87
- children: !simple && /*#__PURE__*/(0, _jsxRuntime.jsx)("ul", {
88
- children: footerElements.map(function (_ref3, index) {
89
- var url = _ref3.url,
90
- label = _ref3.label,
91
- external = _ref3.external;
132
+ children: [!simple && /*#__PURE__*/(0, _jsxRuntime.jsx)("ul", {
133
+ children: footerElements.map(function (element, index) {
92
134
  return /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
93
- children: external ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.ExternalLink, {
94
- href: url,
95
- children: label
96
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
97
- href: url,
98
- children: label
99
- })
135
+ children: renderItem(element)
100
136
  }, index);
101
137
  })
102
- })
138
+ }), resetDialog.confirmDialog, starterContentDialog.confirmDialog]
103
139
  });
104
140
  };
105
141
  var _default = exports["default"] = Footer;
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
5
+ var _react = require("@testing-library/react");
6
+ var _ = _interopRequireDefault(require("./"));
7
+ var _jsxRuntime = require("react/jsx-runtime");
8
+ 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 }; })(); }
9
+ 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); } /**
10
+ * External dependencies.
11
+ */ /**
12
+ * Internal dependencies.
13
+ */ // Footer renders outside the wizard's HashRouter, so there is no MemoryRouter
14
+ // wrapper here on purpose.
15
+ describe('Footer', function () {
16
+ var RESET_URL = 'https://example.test/wp-admin/admin.php?page=newspack-dashboard&newspack_reset=reset';
17
+ var STARTER_CONTENT_URL = 'https://example.test/wp-admin/admin.php?page=newspack-dashboard&newspack_reset=starter-content';
18
+ var assigned;
19
+ var originalLocation;
20
+ var originalUrls;
21
+ var confirmIn = /*#__PURE__*/function () {
22
+ var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator().m(function _callee(name) {
23
+ var _t;
24
+ return _regenerator().w(function (_context) {
25
+ while (1) switch (_context.n) {
26
+ case 0:
27
+ _t = _react.within;
28
+ _context.n = 1;
29
+ return _react.screen.findByRole('dialog');
30
+ case 1:
31
+ return _context.a(2, _t(_context.v).getByRole('button', {
32
+ name: name
33
+ }));
34
+ }
35
+ }, _callee);
36
+ }));
37
+ return function confirmIn(_x) {
38
+ return _ref.apply(this, arguments);
39
+ };
40
+ }();
41
+ beforeEach(function () {
42
+ assigned = [];
43
+ originalLocation = window.location;
44
+ originalUrls = window.newspack_urls;
45
+ delete window.location;
46
+ window.location = {
47
+ get href() {
48
+ return 'https://example.test/wp-admin/admin.php?page=newspack-dashboard';
49
+ },
50
+ set href(value) {
51
+ assigned.push(value);
52
+ }
53
+ };
54
+ window.newspack_urls = {
55
+ support: 'https://help.newspack.com/',
56
+ reset_url: RESET_URL,
57
+ remove_starter_content: STARTER_CONTENT_URL,
58
+ plugin_version: {
59
+ label: 'Newspack 1.0.0'
60
+ }
61
+ };
62
+ });
63
+ afterEach(function () {
64
+ delete window.location;
65
+ window.location = originalLocation;
66
+ if (undefined === originalUrls) {
67
+ delete window.newspack_urls;
68
+ } else {
69
+ window.newspack_urls = originalUrls;
70
+ }
71
+ });
72
+ it('offers no link for a browser gesture to follow', function () {
73
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
74
+ expect(_react.screen.getByRole('button', {
75
+ name: 'Reset Newspack'
76
+ })).not.toHaveAttribute('href');
77
+ expect(_react.screen.getByRole('button', {
78
+ name: 'Remove Starter Content'
79
+ })).not.toHaveAttribute('href');
80
+ });
81
+ it('does not reset on the first click', function () {
82
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
83
+ _react.fireEvent.click(_react.screen.getByRole('button', {
84
+ name: 'Reset Newspack'
85
+ }));
86
+ expect(assigned).toEqual([]);
87
+ });
88
+ it('asks before resetting', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator().m(function _callee2() {
89
+ var _t2;
90
+ return _regenerator().w(function (_context2) {
91
+ while (1) switch (_context2.n) {
92
+ case 0:
93
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
94
+ _react.fireEvent.click(_react.screen.getByRole('button', {
95
+ name: 'Reset Newspack'
96
+ }));
97
+ _t2 = expect;
98
+ _context2.n = 1;
99
+ return _react.screen.findByText(/deletes the Newspack settings/);
100
+ case 1:
101
+ _t2(_context2.v).toBeInTheDocument();
102
+ case 2:
103
+ return _context2.a(2);
104
+ }
105
+ }, _callee2);
106
+ })));
107
+ it('leaves the site alone when the reset is cancelled', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator().m(function _callee3() {
108
+ var cancel;
109
+ return _regenerator().w(function (_context3) {
110
+ while (1) switch (_context3.n) {
111
+ case 0:
112
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
113
+ _react.fireEvent.click(_react.screen.getByRole('button', {
114
+ name: 'Reset Newspack'
115
+ }));
116
+ // The modal's close icon also carries aria-label="Cancel"; this is the text button.
117
+ _context3.n = 1;
118
+ return _react.screen.findAllByRole('button', {
119
+ name: 'Cancel'
120
+ });
121
+ case 1:
122
+ cancel = _context3.v.find(function (button) {
123
+ return 'Cancel' === button.textContent;
124
+ });
125
+ _react.fireEvent.click(cancel);
126
+ expect(assigned).toEqual([]);
127
+ case 2:
128
+ return _context3.a(2);
129
+ }
130
+ }, _callee3);
131
+ })));
132
+ it('resets once confirmed', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator().m(function _callee4() {
133
+ var _t3;
134
+ return _regenerator().w(function (_context4) {
135
+ while (1) switch (_context4.n) {
136
+ case 0:
137
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
138
+ _react.fireEvent.click(_react.screen.getByRole('button', {
139
+ name: 'Reset Newspack'
140
+ }));
141
+ _t3 = _react.fireEvent;
142
+ _context4.n = 1;
143
+ return confirmIn('Reset Newspack');
144
+ case 1:
145
+ _t3.click.call(_t3, _context4.v);
146
+ expect(assigned).toEqual([RESET_URL]);
147
+ case 2:
148
+ return _context4.a(2);
149
+ }
150
+ }, _callee4);
151
+ })));
152
+ it('does not remove the starter content on the first click', function () {
153
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
154
+ _react.fireEvent.click(_react.screen.getByRole('button', {
155
+ name: 'Remove Starter Content'
156
+ }));
157
+ expect(assigned).toEqual([]);
158
+ });
159
+ it('asks before removing the starter content', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator().m(function _callee5() {
160
+ var _t4;
161
+ return _regenerator().w(function (_context5) {
162
+ while (1) switch (_context5.n) {
163
+ case 0:
164
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
165
+ _react.fireEvent.click(_react.screen.getByRole('button', {
166
+ name: 'Remove Starter Content'
167
+ }));
168
+ _t4 = expect;
169
+ _context5.n = 1;
170
+ return _react.screen.findByText(/created as starter content/);
171
+ case 1:
172
+ _t4(_context5.v).toBeInTheDocument();
173
+ case 2:
174
+ return _context5.a(2);
175
+ }
176
+ }, _callee5);
177
+ })));
178
+ it('removes the starter content once confirmed', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator().m(function _callee6() {
179
+ var _t5;
180
+ return _regenerator().w(function (_context6) {
181
+ while (1) switch (_context6.n) {
182
+ case 0:
183
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
184
+ _react.fireEvent.click(_react.screen.getByRole('button', {
185
+ name: 'Remove Starter Content'
186
+ }));
187
+ _t5 = _react.fireEvent;
188
+ _context6.n = 1;
189
+ return confirmIn('Remove Starter Content');
190
+ case 1:
191
+ _t5.click.call(_t5, _context6.v);
192
+ expect(assigned).toEqual([STARTER_CONTENT_URL]);
193
+ case 2:
194
+ return _context6.a(2);
195
+ }
196
+ }, _callee6);
197
+ })));
198
+ it('does not guard the non-destructive links', function () {
199
+ window.newspack_urls.setup_wizard = 'https://example.test/wp-admin/admin.php?page=newspack-setup-wizard';
200
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {}));
201
+ var link = _react.screen.getByRole('link', {
202
+ name: 'Setup Wizard'
203
+ });
204
+ expect(link).toHaveAttribute('href', window.newspack_urls.setup_wizard);
205
+ _react.fireEvent.click(link);
206
+ expect(_react.screen.queryByRole('dialog')).not.toBeInTheDocument();
207
+ });
208
+ });
@@ -2,6 +2,7 @@
2
2
  * Footer
3
3
  */
4
4
 
5
+ @use "../mixins" as mixins;
5
6
  @use "~@wordpress/base-styles/colors" as wp-colors;
6
7
 
7
8
  .newspack-footer {
@@ -31,7 +32,8 @@
31
32
  li {
32
33
  margin: 8px;
33
34
 
34
- a {
35
+ a,
36
+ button {
35
37
  align-items: flex-end;
36
38
  color: inherit;
37
39
  display: flex;
@@ -42,5 +44,19 @@
42
44
  color: wp-colors.$gray-900;
43
45
  }
44
46
  }
47
+
48
+ button {
49
+ appearance: none;
50
+ background: none;
51
+ border: 0;
52
+ cursor: pointer;
53
+ font: inherit;
54
+ padding: 0;
55
+ text-decoration: underline;
56
+
57
+ &:focus-visible {
58
+ @include mixins.wpds-focus-ring;
59
+ }
60
+ }
45
61
  }
46
62
  }
package/dist/cjs/index.js CHANGED
@@ -112,6 +112,12 @@ Object.defineProperty(exports, "DataViews", {
112
112
  return _dataviews["default"];
113
113
  }
114
114
  });
115
+ Object.defineProperty(exports, "DebugBadge", {
116
+ enumerable: true,
117
+ get: function get() {
118
+ return _debugBadge["default"];
119
+ }
120
+ });
115
121
  Object.defineProperty(exports, "Divider", {
116
122
  enumerable: true,
117
123
  get: function get() {
@@ -414,6 +420,7 @@ var _colorPicker = _interopRequireDefault(require("./color-picker"));
414
420
  var _confirmDialog = _interopRequireDefault(require("./confirm-dialog"));
415
421
  var _customSelectControl = _interopRequireDefault(require("./custom-select-control"));
416
422
  var _dataviews = _interopRequireDefault(require("./dataviews"));
423
+ var _debugBadge = _interopRequireDefault(require("./debug-badge"));
417
424
  var _divider = _interopRequireDefault(require("./divider"));
418
425
  var _drawer = _interopRequireDefault(require("./drawer"));
419
426
  var _emptyState = _interopRequireDefault(require("./empty-state"));
@@ -40,7 +40,6 @@ var Notice = /*#__PURE__*/function (_Component) {
40
40
  function render() {
41
41
  var _this$props = this.props,
42
42
  className = _this$props.className,
43
- debugMode = _this$props.debugMode,
44
43
  isError = _this$props.isError,
45
44
  isHandoff = _this$props.isHandoff,
46
45
  isHelp = _this$props.isHelp,
@@ -52,14 +51,12 @@ var Notice = /*#__PURE__*/function (_Component) {
52
51
  style = _this$props$style === void 0 ? {} : _this$props$style,
53
52
  _this$props$children = _this$props.children,
54
53
  children = _this$props$children === void 0 ? null : _this$props$children;
55
- var classes = (0, _classnames["default"])('newspack-notice', className, debugMode && 'newspack-notice__is-debug', isError && 'newspack-notice__is-error', isHandoff && 'newspack-notice__is-handoff', isHelp && 'newspack-notice__is-help', isSuccess && 'newspack-notice__is-success', isWarning && 'newspack-notice__is-warning');
54
+ var classes = (0, _classnames["default"])('newspack-notice', className, isError && 'newspack-notice__is-error', isHandoff && 'newspack-notice__is-handoff', isHelp && 'newspack-notice__is-help', isSuccess && 'newspack-notice__is-success', isWarning && 'newspack-notice__is-warning');
56
55
  var noticeIcon;
57
56
  if (isHelp) {
58
57
  noticeIcon = _icons.help;
59
58
  } else if (isSuccess) {
60
59
  noticeIcon = _icons.check;
61
- } else if (debugMode) {
62
- noticeIcon = _icons.bug;
63
60
  } else {
64
61
  noticeIcon = _icons.info;
65
62
  }
@@ -22,25 +22,6 @@
22
22
  margin-right: 4px;
23
23
  }
24
24
 
25
- &__is-debug {
26
- background: np-colors.$primary-600;
27
- border-radius: 50%;
28
- bottom: 16px;
29
- box-shadow: 0 0 8px 4px rgba(black, 0.08);
30
- color: white;
31
- font-weight: bold;
32
- margin: 0 16px;
33
- padding: 6px;
34
- position: fixed;
35
- text-transform: uppercase;
36
- z-index: 9997;
37
-
38
- > svg {
39
- fill: white;
40
- margin: 0;
41
- }
42
- }
43
-
44
25
  &__is-error {
45
26
  background: color.adjust(wp-colors.$alert-red, $lightness: 35%);
46
27
 
@@ -207,7 +207,7 @@ var PluginToggle = /*#__PURE__*/function (_Component) {
207
207
  return _this2.managePlugin(slug, value);
208
208
  },
209
209
  notification: error,
210
- notificationHTML: error,
210
+ notificationHTML: true,
211
211
  notificationLevel: "error"
212
212
  }, index);
213
213
  });
@@ -115,9 +115,7 @@ function withWizardScreen(WrappedComponent) {
115
115
  }];
116
116
  }
117
117
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
118
- children: [newspack_aux_data.is_debug_mode && /*#__PURE__*/(0, _jsxRuntime.jsx)(_.Notice, {
119
- debugMode: true
120
- }), hideHeader ?
118
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_.DebugBadge, {}), hideHeader ?
121
119
  /*#__PURE__*/
122
120
  // Without the Page shell the tabs still own the content: it
123
121
  // renders inside the active tab's panel.