newspack-components 4.6.2 → 4.7.0-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 +23 -0
- package/colors/colors.module.scss +13 -7
- package/dist/cjs/autocomplete-tokenfield/style.scss +4 -2
- package/dist/cjs/breadcrumbs/format-count.js +33 -0
- package/dist/cjs/breadcrumbs/index.js +78 -20
- package/dist/cjs/breadcrumbs/index.test.js +110 -0
- package/dist/cjs/breadcrumbs/style.scss +6 -0
- package/dist/cjs/button/index.js +41 -17
- package/dist/cjs/button/index.test.js +273 -0
- package/dist/cjs/card/core-card.js +9 -4
- package/dist/cjs/card/core-card.test.js +29 -0
- package/dist/cjs/card/index.js +4 -2
- package/dist/cjs/card/style-core.scss +59 -0
- package/dist/cjs/card-feature/index.js +7 -1
- package/dist/cjs/card-feature/index.test.js +92 -0
- package/dist/cjs/color-picker/index.js +1 -1
- package/dist/cjs/confirm-dialog/index.js +26 -9
- package/dist/cjs/confirm-dialog/index.test.js +176 -0
- package/dist/cjs/dataviews/index.js +11 -2
- package/dist/cjs/divider/index.js +13 -0
- package/dist/cjs/drawer/action.js +74 -0
- package/dist/cjs/drawer/body.js +79 -0
- package/dist/cjs/drawer/close-icon.js +45 -0
- package/dist/cjs/drawer/content.js +72 -0
- package/dist/cjs/drawer/context.js +23 -0
- package/dist/cjs/drawer/context.test.js +43 -0
- package/dist/cjs/drawer/divider.js +24 -0
- package/dist/cjs/drawer/footer.js +26 -0
- package/dist/cjs/drawer/header.js +26 -0
- package/dist/cjs/drawer/index.js +42 -0
- package/dist/cjs/drawer/index.test.js +1287 -0
- package/dist/cjs/drawer/root.js +350 -0
- package/dist/cjs/drawer/slots.test.js +422 -0
- package/dist/cjs/drawer/style.scss +205 -0
- package/dist/cjs/drawer/title.js +54 -0
- package/dist/cjs/drawer/types.js +5 -0
- package/dist/cjs/drawer/use-exit-animation.js +59 -0
- package/dist/cjs/hooks/use-confirm-dialog.js +15 -3
- package/dist/cjs/hooks/use-unsaved-changes-dialog.js +19 -4
- package/dist/cjs/index.js +28 -1
- package/dist/cjs/page/index.js +1 -1
- package/dist/cjs/page-control/index.js +82 -0
- package/dist/cjs/plugin-settings/SettingsSection.js +7 -1
- package/dist/cjs/section-header/index.js +5 -2
- package/dist/cjs/section-header/style.scss +25 -12
- package/dist/cjs/table-card/index.js +67 -0
- package/dist/cjs/table-card/index.test.js +153 -0
- package/dist/cjs/with-wizard-screen/style.scss +8 -0
- package/dist/cjs/wizard/index.js +102 -38
- package/dist/esm/autocomplete-tokenfield/style.scss +4 -2
- package/dist/esm/breadcrumbs/format-count.js +27 -0
- package/dist/esm/breadcrumbs/index.js +81 -20
- package/dist/esm/breadcrumbs/index.test.js +110 -0
- package/dist/esm/breadcrumbs/style.scss +6 -0
- package/dist/esm/button/index.js +42 -18
- package/dist/esm/button/index.test.js +273 -0
- package/dist/esm/card/core-card.js +9 -4
- package/dist/esm/card/core-card.test.js +29 -0
- package/dist/esm/card/index.js +4 -2
- package/dist/esm/card/style-core.scss +59 -0
- package/dist/esm/card-feature/index.js +8 -2
- package/dist/esm/card-feature/index.test.js +96 -0
- package/dist/esm/color-picker/index.js +1 -1
- package/dist/esm/confirm-dialog/index.js +26 -9
- package/dist/esm/confirm-dialog/index.test.js +176 -0
- package/dist/esm/dataviews/index.js +11 -2
- package/dist/esm/divider/index.js +14 -0
- package/dist/esm/drawer/action.js +68 -0
- package/dist/esm/drawer/body.js +70 -0
- package/dist/esm/drawer/close-icon.js +37 -0
- package/dist/esm/drawer/content.js +63 -0
- package/dist/esm/drawer/context.js +17 -0
- package/dist/esm/drawer/context.test.js +40 -0
- package/dist/esm/drawer/divider.js +16 -0
- package/dist/esm/drawer/footer.js +18 -0
- package/dist/esm/drawer/header.js +18 -0
- package/dist/esm/drawer/index.js +35 -0
- package/dist/esm/drawer/index.test.js +1285 -0
- package/dist/esm/drawer/root.js +342 -0
- package/dist/esm/drawer/slots.test.js +422 -0
- package/dist/esm/drawer/style.scss +205 -0
- package/dist/esm/drawer/title.js +46 -0
- package/dist/esm/drawer/types.js +1 -0
- package/dist/esm/drawer/use-exit-animation.js +52 -0
- package/dist/esm/hooks/use-confirm-dialog.js +15 -3
- package/dist/esm/hooks/use-unsaved-changes-dialog.js +20 -5
- package/dist/esm/index.js +4 -0
- package/dist/esm/page/index.js +1 -1
- package/dist/esm/page-control/index.js +82 -0
- package/dist/esm/plugin-settings/SettingsSection.js +8 -2
- package/dist/esm/section-header/index.js +5 -2
- package/dist/esm/section-header/style.scss +25 -12
- package/dist/esm/table-card/index.js +60 -0
- package/dist/esm/table-card/index.test.js +150 -0
- package/dist/esm/with-wizard-screen/style.scss +8 -0
- package/dist/esm/wizard/index.js +104 -38
- package/package.json +2 -2
- package/src/autocomplete-tokenfield/style.scss +4 -2
- package/src/breadcrumbs/format-count.js +27 -0
- package/src/breadcrumbs/index.js +68 -8
- package/src/breadcrumbs/index.test.js +57 -0
- package/src/breadcrumbs/style.scss +6 -0
- package/src/button/index.test.js +143 -0
- package/src/button/index.tsx +32 -7
- package/src/card/core-card.js +15 -2
- package/src/card/core-card.test.js +19 -0
- package/src/card/index.js +3 -0
- package/src/card/style-core.scss +59 -0
- package/src/card-feature/README.md +4 -0
- package/src/card-feature/index.test.js +65 -0
- package/src/card-feature/index.tsx +13 -2
- package/src/color-picker/index.js +1 -1
- package/src/confirm-dialog/README.md +3 -2
- package/src/confirm-dialog/index.test.js +146 -0
- package/src/confirm-dialog/index.tsx +23 -9
- package/src/dataviews/index.tsx +11 -2
- package/src/divider/index.js +13 -0
- package/src/drawer/README.md +454 -0
- package/src/drawer/action.tsx +67 -0
- package/src/drawer/body.tsx +60 -0
- package/src/drawer/close-icon.tsx +37 -0
- package/src/drawer/content.tsx +54 -0
- package/src/drawer/context.test.js +31 -0
- package/src/drawer/context.ts +25 -0
- package/src/drawer/divider.tsx +13 -0
- package/src/drawer/footer.tsx +15 -0
- package/src/drawer/header.tsx +15 -0
- package/src/drawer/index.test.js +1012 -0
- package/src/drawer/index.tsx +33 -0
- package/src/drawer/root.tsx +328 -0
- package/src/drawer/slots.test.js +314 -0
- package/src/drawer/style.scss +205 -0
- package/src/drawer/title.tsx +40 -0
- package/src/drawer/types.ts +79 -0
- package/src/drawer/use-exit-animation.ts +46 -0
- package/src/hooks/use-confirm-dialog.tsx +14 -3
- package/src/hooks/use-unsaved-changes-dialog.tsx +17 -5
- package/src/index.js +4 -0
- package/src/page/index.js +1 -1
- package/src/page-control/index.js +63 -0
- package/src/plugin-settings/SettingsSection.js +8 -2
- package/src/section-header/index.js +5 -2
- package/src/section-header/style.scss +25 -12
- package/src/table-card/README.md +100 -0
- package/src/table-card/index.test.js +112 -0
- package/src/table-card/index.tsx +56 -0
- package/src/with-wizard-screen/style.scss +8 -0
- package/src/wizard/index.js +95 -34
|
@@ -65,6 +65,34 @@ describe('ConfirmDialog navigation blocking', function () {
|
|
|
65
65
|
expect(replaceSpy).toHaveBeenCalledTimes(1);
|
|
66
66
|
expect(history.location.pathname).toBe('/');
|
|
67
67
|
});
|
|
68
|
+
|
|
69
|
+
// v5 keeps a single prompt slot, so an unprompted re-sync would be caught by
|
|
70
|
+
// whichever dialog on the screen did install a blocker.
|
|
71
|
+
it('cancels an unprompted dialog without tripping another blocker', function () {
|
|
72
|
+
var historyRef = {
|
|
73
|
+
current: null
|
|
74
|
+
};
|
|
75
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.MemoryRouter, {
|
|
76
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(HistoryGrabber, {
|
|
77
|
+
historyRef: historyRef
|
|
78
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
79
|
+
when: true,
|
|
80
|
+
confirmButtonText: "Leave",
|
|
81
|
+
cancelButtonText: "Stay",
|
|
82
|
+
children: "Wizard guard"
|
|
83
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
84
|
+
isOpen: true,
|
|
85
|
+
confirmButtonText: "Discard changes",
|
|
86
|
+
cancelButtonText: "Keep editing",
|
|
87
|
+
children: "Unsaved changes"
|
|
88
|
+
})]
|
|
89
|
+
}));
|
|
90
|
+
var replaceSpy = jest.spyOn(historyRef.current, 'replace');
|
|
91
|
+
cancelNavigation();
|
|
92
|
+
expect(dialog()).not.toBeInTheDocument();
|
|
93
|
+
expect(_react.screen.queryByText('Wizard guard')).not.toBeInTheDocument();
|
|
94
|
+
expect(replaceSpy).not.toHaveBeenCalled();
|
|
95
|
+
});
|
|
68
96
|
it('replays a blocked push on confirm: re-sync replace first, then push, and re-arms the blocker', function () {
|
|
69
97
|
var history = renderWithHistory();
|
|
70
98
|
var replaceSpy = jest.spyOn(history, 'replace');
|
|
@@ -170,4 +198,152 @@ describe('ConfirmDialog navigation blocking', function () {
|
|
|
170
198
|
expect(history.location.pathname).toBe('/');
|
|
171
199
|
expect(dialog()).toBeInTheDocument();
|
|
172
200
|
});
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// `useHistory` returns undefined outside a wizard, where `newspack-multibranded-site`
|
|
204
|
+
// runs react-router v6 against this package's v5.
|
|
205
|
+
describe('ConfirmDialog without a router', function () {
|
|
206
|
+
var renderUnrouted = function renderUnrouted() {
|
|
207
|
+
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
208
|
+
return (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], _objectSpread(_objectSpread({
|
|
209
|
+
isOpen: true,
|
|
210
|
+
confirmButtonText: "Discard changes",
|
|
211
|
+
cancelButtonText: "Keep editing"
|
|
212
|
+
}, props), {}, {
|
|
213
|
+
children: "Unsaved changes"
|
|
214
|
+
})));
|
|
215
|
+
};
|
|
216
|
+
it('cancels with no history to re-sync', function () {
|
|
217
|
+
var onCancel = jest.fn();
|
|
218
|
+
renderUnrouted({
|
|
219
|
+
onCancel: onCancel
|
|
220
|
+
});
|
|
221
|
+
expect(dialog()).toBeInTheDocument();
|
|
222
|
+
cancelNavigation();
|
|
223
|
+
expect(onCancel).toHaveBeenCalled();
|
|
224
|
+
expect(dialog()).not.toBeInTheDocument();
|
|
225
|
+
});
|
|
226
|
+
it('confirms with no history to re-sync', function () {
|
|
227
|
+
var onConfirm = jest.fn();
|
|
228
|
+
renderUnrouted({
|
|
229
|
+
onConfirm: onConfirm
|
|
230
|
+
});
|
|
231
|
+
confirmNavigation();
|
|
232
|
+
expect(onConfirm).toHaveBeenCalled();
|
|
233
|
+
expect(dialog()).not.toBeInTheDocument();
|
|
234
|
+
});
|
|
235
|
+
it('installs no blocker when asked to block without a router', function () {
|
|
236
|
+
expect(function () {
|
|
237
|
+
return renderUnrouted({
|
|
238
|
+
when: true
|
|
239
|
+
});
|
|
240
|
+
}).not.toThrow();
|
|
241
|
+
expect(dialog()).toBeInTheDocument();
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe('ConfirmDialog controlled by isOpen', function () {
|
|
245
|
+
var tree = function tree(isOpen) {
|
|
246
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
247
|
+
isOpen: isOpen,
|
|
248
|
+
confirmButtonText: "Discard changes",
|
|
249
|
+
cancelButtonText: "Keep editing",
|
|
250
|
+
children: "Unsaved changes"
|
|
251
|
+
});
|
|
252
|
+
};
|
|
253
|
+
it('closes when isOpen goes false', function () {
|
|
254
|
+
var _render = (0, _react.render)(tree(true)),
|
|
255
|
+
rerender = _render.rerender;
|
|
256
|
+
expect(dialog()).toBeInTheDocument();
|
|
257
|
+
rerender(tree(false));
|
|
258
|
+
expect(dialog()).not.toBeInTheDocument();
|
|
259
|
+
});
|
|
260
|
+
it('opens again afterwards', function () {
|
|
261
|
+
var _render2 = (0, _react.render)(tree(true)),
|
|
262
|
+
rerender = _render2.rerender;
|
|
263
|
+
rerender(tree(false));
|
|
264
|
+
rerender(tree(true));
|
|
265
|
+
expect(dialog()).toBeInTheDocument();
|
|
266
|
+
});
|
|
267
|
+
it('leaves a blocked navigation prompt up', function () {
|
|
268
|
+
var historyRef = {
|
|
269
|
+
current: null
|
|
270
|
+
};
|
|
271
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.MemoryRouter, {
|
|
272
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(HistoryGrabber, {
|
|
273
|
+
historyRef: historyRef
|
|
274
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
275
|
+
when: true,
|
|
276
|
+
isOpen: false,
|
|
277
|
+
confirmButtonText: "Discard changes",
|
|
278
|
+
cancelButtonText: "Keep editing",
|
|
279
|
+
children: "Unsaved changes"
|
|
280
|
+
})]
|
|
281
|
+
}));
|
|
282
|
+
(0, _react.act)(function () {
|
|
283
|
+
return historyRef.current.push('/next');
|
|
284
|
+
});
|
|
285
|
+
expect(dialog()).toBeInTheDocument();
|
|
286
|
+
});
|
|
287
|
+
it('withdraws a blocked navigation prompt when isOpen goes false', function () {
|
|
288
|
+
var historyRef = {
|
|
289
|
+
current: null
|
|
290
|
+
};
|
|
291
|
+
var withOpen = function withOpen(isOpen) {
|
|
292
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactRouterDom.MemoryRouter, {
|
|
293
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(HistoryGrabber, {
|
|
294
|
+
historyRef: historyRef
|
|
295
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
296
|
+
when: true,
|
|
297
|
+
isOpen: isOpen,
|
|
298
|
+
confirmButtonText: "Discard changes",
|
|
299
|
+
cancelButtonText: "Keep editing",
|
|
300
|
+
children: "Unsaved changes"
|
|
301
|
+
})]
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
var _render3 = (0, _react.render)(withOpen(true)),
|
|
305
|
+
rerender = _render3.rerender;
|
|
306
|
+
(0, _react.act)(function () {
|
|
307
|
+
return historyRef.current.push('/next');
|
|
308
|
+
});
|
|
309
|
+
expect(dialog()).toBeInTheDocument();
|
|
310
|
+
rerender(withOpen(false));
|
|
311
|
+
expect(dialog()).not.toBeInTheDocument();
|
|
312
|
+
expect(historyRef.current.location.pathname).toBe('/');
|
|
313
|
+
|
|
314
|
+
// Confirming the next prompt must not replay the abandoned destination.
|
|
315
|
+
rerender(withOpen(true));
|
|
316
|
+
confirmNavigation();
|
|
317
|
+
expect(historyRef.current.location.pathname).toBe('/');
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
describe('ConfirmDialog named by a hidden title', function () {
|
|
321
|
+
it('takes its accessible name from the title while hiding the header', function () {
|
|
322
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
323
|
+
isOpen: true,
|
|
324
|
+
hideTitle: true,
|
|
325
|
+
title: "Unsaved changes",
|
|
326
|
+
confirmButtonText: "Discard changes",
|
|
327
|
+
children: "You have unsaved changes that will be lost. Discard changes?"
|
|
328
|
+
}));
|
|
329
|
+
var frame = _react.screen.getByRole('dialog', {
|
|
330
|
+
name: 'Unsaved changes'
|
|
331
|
+
});
|
|
332
|
+
expect(frame).toHaveClass('newspack-modal--hide-title');
|
|
333
|
+
expect(frame.querySelector('.components-modal__header')).toContainElement(_react.screen.getByRole('heading', {
|
|
334
|
+
name: 'Unsaved changes'
|
|
335
|
+
}));
|
|
336
|
+
});
|
|
337
|
+
it('has no accessible name without a title', function () {
|
|
338
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
339
|
+
isOpen: true,
|
|
340
|
+
hideTitle: true,
|
|
341
|
+
confirmButtonText: "Discard changes",
|
|
342
|
+
children: "You have unsaved changes that will be lost. Discard changes?"
|
|
343
|
+
}));
|
|
344
|
+
expect(_react.screen.queryByRole('dialog', {
|
|
345
|
+
name: 'Unsaved changes'
|
|
346
|
+
})).not.toBeInTheDocument();
|
|
347
|
+
expect(_react.screen.getByRole('dialog')).not.toHaveAttribute('aria-labelledby');
|
|
348
|
+
});
|
|
173
349
|
});
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports["default"] =
|
|
7
|
+
exports["default"] = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
10
10
|
var _dataviews = require("@wordpress/dataviews");
|
|
@@ -35,4 +35,13 @@ function DataViews(_ref) {
|
|
|
35
35
|
className: (0, _classnames["default"])('newspack-dataviews', className),
|
|
36
36
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataviews.DataViews, _objectSpread({}, props))
|
|
37
37
|
});
|
|
38
|
-
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The implementation is typed against the `unknown` instantiation because
|
|
41
|
+
// BaseDataViews' conditionally-optional `getItemId` prop cannot be related
|
|
42
|
+
// to a JSX spread while `Item` is an unresolved type parameter. The export
|
|
43
|
+
// re-types it with the generic signature so call sites get item-aware
|
|
44
|
+
// typing for `data`, `fields`, `actions`, `getItemId`, etc. The assertion
|
|
45
|
+
// is verified by the compiler: the generic signature is assignable to the
|
|
46
|
+
// implementation's concrete one.
|
|
47
|
+
var _default = exports["default"] = DataViews;
|
|
@@ -20,6 +20,19 @@ var _excluded = ["alignment", "className", "marginBottom", "marginTop", "variant
|
|
|
20
20
|
/**
|
|
21
21
|
* External dependencies
|
|
22
22
|
*/
|
|
23
|
+
/**
|
|
24
|
+
* Divider component.
|
|
25
|
+
*
|
|
26
|
+
* Every prop beyond the documented ones is forwarded to the `hr` element.
|
|
27
|
+
*
|
|
28
|
+
* @param {import('react').ComponentPropsWithoutRef<'hr'> & {
|
|
29
|
+
* alignment?: string,
|
|
30
|
+
* marginBottom?: number|string,
|
|
31
|
+
* marginTop?: number|string,
|
|
32
|
+
* variant?: string,
|
|
33
|
+
* }} props - Component props: the documented options plus any `hr` attribute.
|
|
34
|
+
* @return {JSX.Element} Divider component.
|
|
35
|
+
*/
|
|
23
36
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
24
37
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
25
38
|
var Divider = function Divider(_ref) {
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
10
|
+
var _element = require("@wordpress/element");
|
|
11
|
+
var _button = _interopRequireDefault(require("../button"));
|
|
12
|
+
var _context = require("./context");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
var _excluded = ["ariaLabel", "closes", "onClick", "href", "children"];
|
|
15
|
+
/**
|
|
16
|
+
* WordPress dependencies.
|
|
17
|
+
*/
|
|
18
|
+
/**
|
|
19
|
+
* Internal dependencies.
|
|
20
|
+
*/
|
|
21
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
22
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
23
|
+
var Action = function Action(_ref) {
|
|
24
|
+
var ariaLabel = _ref.ariaLabel,
|
|
25
|
+
_ref$closes = _ref.closes,
|
|
26
|
+
closes = _ref$closes === void 0 ? false : _ref$closes,
|
|
27
|
+
onClick = _ref.onClick,
|
|
28
|
+
href = _ref.href,
|
|
29
|
+
children = _ref.children,
|
|
30
|
+
buttonProps = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
|
|
31
|
+
// Not useDrawerContext: only `closes` requires the context.
|
|
32
|
+
var context = (0, _element.useContext)(_context.DrawerContext);
|
|
33
|
+
|
|
34
|
+
// `href=""` is still an anchor; a null from a JS caller means no link at all.
|
|
35
|
+
var hasHref = 'string' === typeof href;
|
|
36
|
+
(0, _element.useEffect)(function () {
|
|
37
|
+
if ('production' === process.env.NODE_ENV || !hasHref) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (onClick || closes) {
|
|
41
|
+
// eslint-disable-next-line no-console
|
|
42
|
+
console.warn('Drawer: an action with `href` cannot also take `onClick` or `closes`, and they are ignored. ' + 'A link that ran the close funnel would navigate away while the unsaved-changes confirmation was still opening.');
|
|
43
|
+
}
|
|
44
|
+
}, [hasHref, onClick, closes]);
|
|
45
|
+
(0, _element.useEffect)(function () {
|
|
46
|
+
if ('production' === process.env.NODE_ENV) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (typeof children === 'string' && ariaLabel && !ariaLabel.toLowerCase().includes(children.toLowerCase())) {
|
|
50
|
+
// eslint-disable-next-line no-console
|
|
51
|
+
console.warn("Drawer: action ariaLabel \"".concat(ariaLabel, "\" does not contain its visible label \"").concat(children, "\". ") + 'Voice control matches spoken commands against the accessible name (WCAG 2.5.3, Label in Name), ' + 'so ariaLabel must extend the visible text rather than replace it.');
|
|
52
|
+
}
|
|
53
|
+
}, [ariaLabel, children]);
|
|
54
|
+
var handleClick = function handleClick(event) {
|
|
55
|
+
onClick === null || onClick === void 0 || onClick(event);
|
|
56
|
+
if (closes) {
|
|
57
|
+
if (!context) {
|
|
58
|
+
throw new Error('Drawer subcomponents must be rendered inside Drawer.Root.');
|
|
59
|
+
}
|
|
60
|
+
context.requestClose();
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Button swallows `href` whenever an onClick is present, so a link supplies none.
|
|
65
|
+
var handlesClick = !hasHref && (!!onClick || closes);
|
|
66
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_button["default"], _objectSpread(_objectSpread({
|
|
67
|
+
"aria-label": ariaLabel,
|
|
68
|
+
href: hasHref ? href : undefined,
|
|
69
|
+
onClick: handlesClick ? handleClick : undefined
|
|
70
|
+
}, buttonProps), {}, {
|
|
71
|
+
children: children
|
|
72
|
+
}));
|
|
73
|
+
};
|
|
74
|
+
var _default = exports["default"] = Action;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _components = require("@wordpress/components");
|
|
10
|
+
var _element = require("@wordpress/element");
|
|
11
|
+
var _i18n = require("@wordpress/i18n");
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
/**
|
|
14
|
+
* WordPress dependencies.
|
|
15
|
+
*/
|
|
16
|
+
// eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Internal dependencies.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
// Core tab-stops its own container once it overflows; the drawer scrolls here.
|
|
23
|
+
var Body = function Body(_ref) {
|
|
24
|
+
var children = _ref.children;
|
|
25
|
+
var _useState = (0, _element.useState)(null),
|
|
26
|
+
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
|
|
27
|
+
node = _useState2[0],
|
|
28
|
+
setNode = _useState2[1];
|
|
29
|
+
var _useState3 = (0, _element.useState)(false),
|
|
30
|
+
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
|
|
31
|
+
isScrollable = _useState4[0],
|
|
32
|
+
setIsScrollable = _useState4[1];
|
|
33
|
+
(0, _element.useEffect)(function () {
|
|
34
|
+
if (!node) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
var measure = function measure() {
|
|
38
|
+
return setIsScrollable(node.scrollHeight > node.clientHeight);
|
|
39
|
+
};
|
|
40
|
+
measure();
|
|
41
|
+
if (!window.ResizeObserver) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
var resize = new ResizeObserver(measure);
|
|
45
|
+
var observeChildren = function observeChildren() {
|
|
46
|
+
resize.disconnect();
|
|
47
|
+
resize.observe(node);
|
|
48
|
+
// Border box: a section's padding rides on an inline custom property.
|
|
49
|
+
Array.from(node.children).forEach(function (child) {
|
|
50
|
+
return resize.observe(child, {
|
|
51
|
+
box: 'border-box'
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
measure();
|
|
55
|
+
};
|
|
56
|
+
observeChildren();
|
|
57
|
+
var mutation = new MutationObserver(observeChildren);
|
|
58
|
+
mutation.observe(node, {
|
|
59
|
+
childList: true
|
|
60
|
+
});
|
|
61
|
+
return function () {
|
|
62
|
+
resize.disconnect();
|
|
63
|
+
mutation.disconnect();
|
|
64
|
+
};
|
|
65
|
+
}, [node]);
|
|
66
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalVStack, {
|
|
67
|
+
ref: setNode,
|
|
68
|
+
className: "newspack-drawer__body",
|
|
69
|
+
spacing: 0,
|
|
70
|
+
justify: "flex-start"
|
|
71
|
+
// A bare div is role=generic, where ARIA prohibits an author name.
|
|
72
|
+
,
|
|
73
|
+
role: isScrollable ? 'group' : undefined,
|
|
74
|
+
tabIndex: isScrollable ? 0 : undefined,
|
|
75
|
+
"aria-label": isScrollable ? (0, _i18n.__)('Scrollable section', 'newspack-plugin') : undefined,
|
|
76
|
+
children: children
|
|
77
|
+
});
|
|
78
|
+
};
|
|
79
|
+
var _default = exports["default"] = Body;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _icons = require("@wordpress/icons");
|
|
9
|
+
var _i18n = require("@wordpress/i18n");
|
|
10
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
|
+
var _button = _interopRequireDefault(require("../button"));
|
|
12
|
+
var _context = require("./context");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
/**
|
|
15
|
+
* WordPress dependencies.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* External dependencies.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Internal dependencies.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
var CloseIcon = function CloseIcon(_ref) {
|
|
27
|
+
var label = _ref.label,
|
|
28
|
+
_ref$icon = _ref.icon,
|
|
29
|
+
icon = _ref$icon === void 0 ? _icons.close : _ref$icon,
|
|
30
|
+
className = _ref.className;
|
|
31
|
+
var _useDrawerContext = (0, _context.useDrawerContext)(),
|
|
32
|
+
requestClose = _useDrawerContext.requestClose,
|
|
33
|
+
title = _useDrawerContext.title;
|
|
34
|
+
var defaultLabel = title !== null && title !== void 0 && title.text ?
|
|
35
|
+
// translators: %s: the drawer's title.
|
|
36
|
+
(0, _i18n.sprintf)((0, _i18n.__)('Close %s', 'newspack-plugin'), title.text) : (0, _i18n.__)('Close', 'newspack-plugin');
|
|
37
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_button["default"], {
|
|
38
|
+
className: (0, _classnames["default"])('newspack-drawer__dismiss', className),
|
|
39
|
+
icon: icon,
|
|
40
|
+
size: "small",
|
|
41
|
+
label: label || defaultLabel,
|
|
42
|
+
onClick: requestClose
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
var _default = exports["default"] = CloseIcon;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _components = require("@wordpress/components");
|
|
9
|
+
var _element = require("@wordpress/element");
|
|
10
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
|
+
/**
|
|
13
|
+
* WordPress dependencies.
|
|
14
|
+
*/
|
|
15
|
+
// eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* External dependencies.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Internal dependencies.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
// VStack drops non-elements, a lone string aside. A run shares one wrapper so
|
|
26
|
+
// `Edited by { name }` is one row, not three.
|
|
27
|
+
var asRows = function asRows(children) {
|
|
28
|
+
if ('string' === typeof children) {
|
|
29
|
+
return children;
|
|
30
|
+
}
|
|
31
|
+
var rows = [];
|
|
32
|
+
var text = [];
|
|
33
|
+
var flushText = function flushText() {
|
|
34
|
+
if (text.some(function (part) {
|
|
35
|
+
return '' !== String(part).trim();
|
|
36
|
+
})) {
|
|
37
|
+
rows.push(/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
38
|
+
children: text
|
|
39
|
+
}, "text-".concat(rows.length)));
|
|
40
|
+
}
|
|
41
|
+
text = [];
|
|
42
|
+
};
|
|
43
|
+
_element.Children.toArray(children).forEach(function (child) {
|
|
44
|
+
if ((0, _element.isValidElement)(child)) {
|
|
45
|
+
flushText();
|
|
46
|
+
rows.push(child);
|
|
47
|
+
} else {
|
|
48
|
+
text.push(child);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
flushText();
|
|
52
|
+
return rows;
|
|
53
|
+
};
|
|
54
|
+
var Content = function Content(_ref) {
|
|
55
|
+
var _ref$padding = _ref.padding,
|
|
56
|
+
padding = _ref$padding === void 0 ? 6 : _ref$padding,
|
|
57
|
+
_ref$gap = _ref.gap,
|
|
58
|
+
gap = _ref$gap === void 0 ? 4 : _ref$gap,
|
|
59
|
+
className = _ref.className,
|
|
60
|
+
children = _ref.children;
|
|
61
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalVStack, {
|
|
62
|
+
className: (0, _classnames["default"])('newspack-drawer__content', className),
|
|
63
|
+
spacing: gap
|
|
64
|
+
// A custom property, not inline padding, so the stylesheet's seam rules win.
|
|
65
|
+
,
|
|
66
|
+
style: {
|
|
67
|
+
'--newspack-drawer-content-padding': "".concat(padding * 4, "px")
|
|
68
|
+
},
|
|
69
|
+
children: asRows(children)
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
var _default = exports["default"] = Content;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useDrawerContext = exports.DrawerContext = void 0;
|
|
7
|
+
var _element = require("@wordpress/element");
|
|
8
|
+
/**
|
|
9
|
+
* WordPress dependencies.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Internal dependencies.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
var DrawerContext = exports.DrawerContext = (0, _element.createContext)(null);
|
|
17
|
+
var useDrawerContext = exports.useDrawerContext = function useDrawerContext() {
|
|
18
|
+
var context = (0, _element.useContext)(DrawerContext);
|
|
19
|
+
if (!context) {
|
|
20
|
+
throw new Error('Drawer subcomponents must be rendered inside Drawer.Root.');
|
|
21
|
+
}
|
|
22
|
+
return context;
|
|
23
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _context = require("./context");
|
|
4
|
+
var _react = require("@testing-library/react");
|
|
5
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* External dependencies.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
var Probe = function Probe() {
|
|
15
|
+
var _useDrawerContext = (0, _context.useDrawerContext)(),
|
|
16
|
+
title = _useDrawerContext.title;
|
|
17
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
18
|
+
children: title ? title.text : 'no title'
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
describe('useDrawerContext', function () {
|
|
22
|
+
it('returns the provided value', function () {
|
|
23
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_context.DrawerContext.Provider, {
|
|
24
|
+
value: {
|
|
25
|
+
requestClose: function requestClose() {},
|
|
26
|
+
title: {
|
|
27
|
+
id: 't1',
|
|
28
|
+
text: 'Hello'
|
|
29
|
+
},
|
|
30
|
+
setTitle: function setTitle() {}
|
|
31
|
+
},
|
|
32
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Probe, {})
|
|
33
|
+
}));
|
|
34
|
+
expect(_react.screen.getByText('Hello')).toBeInTheDocument();
|
|
35
|
+
});
|
|
36
|
+
it('throws outside Drawer.Root', function () {
|
|
37
|
+
var consoleError = jest.spyOn(console, 'error').mockImplementation(function () {});
|
|
38
|
+
expect(function () {
|
|
39
|
+
return (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Probe, {}));
|
|
40
|
+
}).toThrow('Drawer subcomponents must be rendered inside Drawer.Root.');
|
|
41
|
+
consoleError.mockRestore();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
/**
|
|
11
|
+
* External dependencies.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Internal dependencies.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
var Divider = function Divider(_ref) {
|
|
19
|
+
var className = _ref.className;
|
|
20
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("hr", {
|
|
21
|
+
className: (0, _classnames["default"])('newspack-drawer__divider', className)
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
var _default = exports["default"] = Divider;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
/**
|
|
11
|
+
* External dependencies.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Internal dependencies.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
var Footer = function Footer(_ref) {
|
|
19
|
+
var className = _ref.className,
|
|
20
|
+
children = _ref.children;
|
|
21
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
22
|
+
className: (0, _classnames["default"])('newspack-drawer__footer', className),
|
|
23
|
+
children: children
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var _default = exports["default"] = Footer;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports["default"] = void 0;
|
|
8
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
/**
|
|
11
|
+
* External dependencies.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Internal dependencies.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
var Header = function Header(_ref) {
|
|
19
|
+
var className = _ref.className,
|
|
20
|
+
children = _ref.children;
|
|
21
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
22
|
+
className: (0, _classnames["default"])('newspack-drawer__header', className),
|
|
23
|
+
children: children
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
var _default = exports["default"] = Header;
|