newspack-components 4.5.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/DEVELOPMENT.md +1 -1
- package/dist/cjs/accordion/index.js +43 -26
- package/dist/cjs/accordion/index.test.js +80 -0
- package/dist/cjs/accordion/style.scss +25 -21
- package/dist/cjs/action-card/style.scss +0 -22
- package/dist/cjs/breadcrumbs/index.js +80 -0
- package/dist/cjs/breadcrumbs/index.test.js +109 -0
- package/dist/cjs/breadcrumbs/style.scss +41 -0
- package/dist/cjs/card/core-card.js +8 -4
- package/dist/cjs/card/index.js +1 -1
- package/dist/cjs/card/style-core.scss +14 -0
- package/dist/cjs/card/style.scss +0 -9
- package/dist/cjs/card-feature/index.js +25 -13
- package/dist/cjs/card-settings-group/index.js +3 -0
- package/dist/cjs/confirm-dialog/index.js +34 -8
- package/dist/cjs/confirm-dialog/index.test.js +173 -0
- package/dist/cjs/divider/style.scss +4 -2
- package/dist/cjs/grid/style.scss +5 -0
- package/dist/cjs/handoff/index.js +8 -5
- package/dist/cjs/index.js +34 -1
- package/dist/cjs/integration-icon/index.js +40 -0
- package/dist/cjs/integration-icon/style.scss +42 -0
- package/dist/cjs/integration-icons/index.js +21 -2
- package/dist/cjs/modal/style.scss +4 -0
- package/dist/cjs/page/index.js +121 -0
- package/dist/cjs/page/index.test.js +69 -0
- package/dist/cjs/page/style.scss +86 -0
- package/dist/cjs/route-match.js +59 -0
- package/dist/cjs/route-match.test.js +77 -0
- package/dist/cjs/section-header/index.js +8 -1
- package/dist/cjs/section-header/style.scss +11 -11
- package/dist/cjs/select-control/GroupedSelectControl.js +1 -1
- package/dist/cjs/select-control/style.scss +4 -0
- package/dist/cjs/style.scss +1 -4
- package/dist/cjs/tabbed-navigation/index.js +188 -40
- package/dist/cjs/tabbed-navigation/index.test.js +299 -0
- package/dist/cjs/tabbed-navigation/style.scss +77 -57
- package/dist/cjs/with-wizard/index.js +34 -45
- package/dist/cjs/with-wizard-screen/index.js +82 -41
- package/dist/cjs/with-wizard-screen/index.test.js +50 -0
- package/dist/cjs/with-wizard-screen/style.scss +15 -118
- package/dist/cjs/wizard/breadcrumbs-select.js +70 -0
- package/dist/cjs/wizard/breadcrumbs-select.test.js +200 -0
- package/dist/cjs/wizard/components/WizardError.js +8 -4
- package/dist/cjs/wizard/index.js +162 -141
- package/dist/esm/accordion/index.js +42 -26
- package/dist/esm/accordion/index.test.js +79 -0
- package/dist/esm/accordion/style.scss +25 -21
- package/dist/esm/action-card/style.scss +0 -22
- package/dist/esm/breadcrumbs/index.js +75 -0
- package/dist/esm/breadcrumbs/index.test.js +105 -0
- package/dist/esm/breadcrumbs/style.scss +41 -0
- package/dist/esm/card/core-card.js +8 -4
- package/dist/esm/card/index.js +1 -1
- package/dist/esm/card/style-core.scss +14 -0
- package/dist/esm/card/style.scss +0 -9
- package/dist/esm/card-feature/index.js +25 -13
- package/dist/esm/card-settings-group/index.js +3 -0
- package/dist/esm/confirm-dialog/index.js +34 -8
- package/dist/esm/confirm-dialog/index.test.js +173 -0
- package/dist/esm/divider/style.scss +4 -2
- package/dist/esm/grid/style.scss +5 -0
- package/dist/esm/handoff/index.js +7 -5
- package/dist/esm/index.js +5 -1
- package/dist/esm/integration-icon/index.js +34 -0
- package/dist/esm/integration-icon/style.scss +42 -0
- package/dist/esm/integration-icons/index.js +22 -1
- package/dist/esm/modal/style.scss +4 -0
- package/dist/esm/page/index.js +113 -0
- package/dist/esm/page/index.test.js +65 -0
- package/dist/esm/page/style.scss +86 -0
- package/dist/esm/route-match.js +51 -0
- package/dist/esm/route-match.test.js +74 -0
- package/dist/esm/section-header/index.js +8 -1
- package/dist/esm/section-header/style.scss +11 -11
- package/dist/esm/select-control/GroupedSelectControl.js +1 -1
- package/dist/esm/select-control/style.scss +4 -0
- package/dist/esm/style.scss +1 -4
- package/dist/esm/tabbed-navigation/index.js +192 -38
- package/dist/esm/tabbed-navigation/index.test.js +296 -0
- package/dist/esm/tabbed-navigation/style.scss +77 -57
- package/dist/esm/with-wizard/index.js +33 -45
- package/dist/esm/with-wizard-screen/index.js +78 -41
- package/dist/esm/with-wizard-screen/index.test.js +46 -0
- package/dist/esm/with-wizard-screen/style.scss +15 -118
- package/dist/esm/wizard/breadcrumbs-select.js +63 -0
- package/dist/esm/wizard/breadcrumbs-select.test.js +197 -0
- package/dist/esm/wizard/components/WizardError.js +7 -5
- package/dist/esm/wizard/index.js +165 -144
- package/package.json +10 -2
- package/src/accordion/index.js +27 -15
- package/src/accordion/index.test.js +62 -0
- package/src/accordion/style.scss +25 -21
- package/src/action-card/style.scss +0 -22
- package/src/breadcrumbs/index.js +63 -0
- package/src/breadcrumbs/index.test.js +59 -0
- package/src/breadcrumbs/style.scss +41 -0
- package/src/card/core-card.js +11 -6
- package/src/card/index.js +0 -1
- package/src/card/style-core.scss +14 -0
- package/src/card/style.scss +0 -9
- package/src/card-feature/README.md +3 -3
- package/src/card-feature/index.tsx +37 -21
- package/src/card-settings-group/index.tsx +4 -0
- package/src/card-sortable-list/index.tsx +1 -1
- package/src/confirm-dialog/index.test.js +142 -0
- package/src/confirm-dialog/index.tsx +34 -7
- package/src/divider/style.scss +4 -2
- package/src/grid/style.scss +5 -0
- package/src/handoff/index.js +4 -3
- package/src/index.js +5 -1
- package/src/integration-icon/index.tsx +35 -0
- package/src/integration-icon/style.scss +42 -0
- package/src/integration-icons/index.js +23 -0
- package/src/modal/style.scss +4 -0
- package/src/page/index.js +89 -0
- package/src/page/index.test.js +43 -0
- package/src/page/style.scss +86 -0
- package/src/route-match.js +47 -0
- package/src/route-match.test.js +50 -0
- package/src/section-header/index.js +7 -3
- package/src/section-header/style.scss +11 -11
- package/src/select-control/GroupedSelectControl.js +1 -1
- package/src/select-control/style.scss +4 -0
- package/src/style.scss +1 -4
- package/src/tabbed-navigation/index.js +181 -34
- package/src/tabbed-navigation/index.test.js +228 -0
- package/src/tabbed-navigation/style.scss +77 -57
- package/src/with-wizard/index.js +18 -39
- package/src/with-wizard-screen/index.js +70 -35
- package/src/with-wizard-screen/index.test.js +36 -0
- package/src/with-wizard-screen/style.scss +15 -118
- package/src/wizard/breadcrumbs-select.js +51 -0
- package/src/wizard/breadcrumbs-select.test.js +124 -0
- package/src/wizard/components/WizardError.js +4 -3
- package/src/wizard/index.js +160 -146
- package/tsconfig.json +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
# newspack-components [4.6.0](https://github.com/Automattic/newspack-workspace/compare/newspack-components@4.5.0...newspack-components@4.6.0) (2026-08-03)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* **audience:** unblock the ESP connect flow in Integrations ([#258](https://github.com/Automattic/newspack-workspace/issues/258)) ([93f3a67](https://github.com/Automattic/newspack-workspace/commit/93f3a67a825b95e0e0f43ac09dad536ee5ccf6f2))
|
|
7
|
+
* **components:** balance section-header description text-wrap ([#624](https://github.com/Automattic/newspack-workspace/issues/624)) ([e6b7076](https://github.com/Automattic/newspack-workspace/commit/e6b70764f63ad98c781ae648728e92819308ace5))
|
|
8
|
+
* **components:** render routed content when no tab owns the route ([#672](https://github.com/Automattic/newspack-workspace/issues/672)) ([ff2ba8d](https://github.com/Automattic/newspack-workspace/commit/ff2ba8d3182e6be0e8e1ebdb7a7af666786ba93e))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* explicit breadcrumb API for Newspack admin headers ([#472](https://github.com/Automattic/newspack-workspace/issues/472)) ([7c43233](https://github.com/Automattic/newspack-workspace/commit/7c4323301f5323822937e93274c4fda4279a787f))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Dependencies
|
|
17
|
+
|
|
18
|
+
* **newspack-icons:** upgraded to 1.1.0
|
|
19
|
+
* **newspack-scripts:** upgraded to 5.10.0
|
|
20
|
+
|
|
21
|
+
# newspack-components [4.6.0-alpha.1](https://github.com/Automattic/newspack-workspace/compare/newspack-components@4.5.0...newspack-components@4.6.0-alpha.1) (2026-07-23)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
### Bug Fixes
|
|
25
|
+
|
|
26
|
+
* **audience:** unblock the ESP connect flow in Integrations ([#258](https://github.com/Automattic/newspack-workspace/issues/258)) ([93f3a67](https://github.com/Automattic/newspack-workspace/commit/93f3a67a825b95e0e0f43ac09dad536ee5ccf6f2))
|
|
27
|
+
* **components:** balance section-header description text-wrap ([#624](https://github.com/Automattic/newspack-workspace/issues/624)) ([e6b7076](https://github.com/Automattic/newspack-workspace/commit/e6b70764f63ad98c781ae648728e92819308ace5))
|
|
28
|
+
* **components:** render routed content when no tab owns the route ([#672](https://github.com/Automattic/newspack-workspace/issues/672)) ([ff2ba8d](https://github.com/Automattic/newspack-workspace/commit/ff2ba8d3182e6be0e8e1ebdb7a7af666786ba93e))
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Features
|
|
32
|
+
|
|
33
|
+
* explicit breadcrumb API for Newspack admin headers ([#472](https://github.com/Automattic/newspack-workspace/issues/472)) ([7c43233](https://github.com/Automattic/newspack-workspace/commit/7c4323301f5323822937e93274c4fda4279a787f))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
### Dependencies
|
|
37
|
+
|
|
38
|
+
* **newspack-icons:** upgraded to 1.1.0-alpha.1
|
|
39
|
+
* **newspack-scripts:** upgraded to 5.10.0-alpha.1
|
|
40
|
+
|
|
1
41
|
# newspack-components [4.5.0](https://github.com/Automattic/newspack-workspace/compare/newspack-components@4.4.0...newspack-components@4.5.0) (2026-07-20)
|
|
2
42
|
|
|
3
43
|
|
package/DEVELOPMENT.md
CHANGED
|
@@ -100,7 +100,7 @@ When building a screen, use the **spacing scale** (8px unit: 16, 24, 32, 48, 64)
|
|
|
100
100
|
- **`Notice`** – Use for outcome feedback (success/error/warning) or short contextual messages. Vertical margin is 32px so notices don’t collide with cards; keep one primary message per area when possible.
|
|
101
101
|
- **`Waiting`** – Loading state indicator.
|
|
102
102
|
- **`ProgressBar`** – Progress indicator.
|
|
103
|
-
- **`Accordion`** –
|
|
103
|
+
- **`Accordion`** / **`AccordionPanel`** – Container for one or more collapsible panels.
|
|
104
104
|
- **`StepsList`** / **`StepsListItem`** – Step-by-step list components.
|
|
105
105
|
- **`StyleCard`** – Style preview card.
|
|
106
106
|
|
|
@@ -4,16 +4,17 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports["default"] = void 0;
|
|
8
|
-
var
|
|
7
|
+
exports["default"] = exports.AccordionPanel = void 0;
|
|
8
|
+
var _components = require("@wordpress/components");
|
|
9
9
|
var _element = require("@wordpress/element");
|
|
10
|
-
var _icons = require("@wordpress/icons");
|
|
11
10
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
11
|
+
var _divider = _interopRequireDefault(require("../divider"));
|
|
12
12
|
require("./style.scss");
|
|
13
13
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
14
|
/**
|
|
15
15
|
* WordPress dependencies
|
|
16
16
|
*/
|
|
17
|
+
// eslint-disable-line @wordpress/no-unsafe-wp-apis
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* External dependencies
|
|
@@ -23,33 +24,49 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
23
24
|
* Internal dependencies
|
|
24
25
|
*/
|
|
25
26
|
|
|
26
|
-
var
|
|
27
|
+
var AccordionPanel = exports.AccordionPanel = function AccordionPanel(_ref) {
|
|
27
28
|
var children = _ref.children,
|
|
29
|
+
className = _ref.className,
|
|
28
30
|
title = _ref.title,
|
|
29
31
|
_ref$defaultOpen = _ref.defaultOpen,
|
|
30
32
|
defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
33
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.PanelBody, {
|
|
34
|
+
className: className,
|
|
35
|
+
title: title,
|
|
36
|
+
initialOpen: defaultOpen,
|
|
37
|
+
children: children
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
var Accordion = function Accordion(_ref2) {
|
|
41
|
+
var children = _ref2.children,
|
|
42
|
+
className = _ref2.className,
|
|
43
|
+
_ref2$hideSingleTitle = _ref2.hideSingleTitle,
|
|
44
|
+
hideSingleTitle = _ref2$hideSingleTitle === void 0 ? false : _ref2$hideSingleTitle,
|
|
45
|
+
_ref2$spacing = _ref2.spacing,
|
|
46
|
+
spacing = _ref2$spacing === void 0 ? 6 : _ref2$spacing;
|
|
47
|
+
var panels = _element.Children.toArray(children);
|
|
48
|
+
// With nothing to collapse against, a lone panel can render open and untitled.
|
|
49
|
+
if (hideSingleTitle && panels.length === 1) {
|
|
50
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
51
|
+
className: (0, _classnames["default"])('newspack-accordion', className),
|
|
52
|
+
children: (0, _element.cloneElement)(panels[0], {
|
|
53
|
+
defaultOpen: true,
|
|
54
|
+
title: undefined
|
|
55
|
+
})
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_components.__experimentalVStack, {
|
|
59
|
+
className: (0, _classnames["default"])('newspack-accordion', className),
|
|
60
|
+
spacing: spacing,
|
|
61
|
+
children: panels.map(function (panel, index) {
|
|
62
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_element.Fragment, {
|
|
63
|
+
children: [panel, index < panels.length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_divider["default"], {
|
|
64
|
+
variant: "secondary",
|
|
65
|
+
marginBottom: 0,
|
|
66
|
+
marginTop: 0
|
|
67
|
+
})]
|
|
68
|
+
}, panel.key);
|
|
69
|
+
})
|
|
53
70
|
});
|
|
54
71
|
};
|
|
55
72
|
var _default = exports["default"] = Accordion;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
5
|
+
var _react = require("@testing-library/react");
|
|
6
|
+
var _index = _interopRequireWildcard(require("./index"));
|
|
7
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
8
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
9
|
+
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; }
|
|
10
|
+
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; } /**
|
|
11
|
+
* External dependencies
|
|
12
|
+
*/ /**
|
|
13
|
+
* Internal dependencies
|
|
14
|
+
*/
|
|
15
|
+
var renderPanels = function renderPanels(count) {
|
|
16
|
+
var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
17
|
+
return (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"], _objectSpread(_objectSpread({}, props), {}, {
|
|
18
|
+
children: Array.from({
|
|
19
|
+
length: count
|
|
20
|
+
}, function (_, i) {
|
|
21
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.AccordionPanel, {
|
|
22
|
+
title: "Panel ".concat(i),
|
|
23
|
+
children: "content"
|
|
24
|
+
}, i);
|
|
25
|
+
})
|
|
26
|
+
})));
|
|
27
|
+
};
|
|
28
|
+
var dividers = function dividers(container) {
|
|
29
|
+
return container.querySelectorAll('.newspack-divider');
|
|
30
|
+
};
|
|
31
|
+
describe('Accordion dividers', function () {
|
|
32
|
+
it('renders no divider for a single panel', function () {
|
|
33
|
+
var _renderPanels = renderPanels(1),
|
|
34
|
+
container = _renderPanels.container;
|
|
35
|
+
expect(container.querySelectorAll('.components-panel__body')).toHaveLength(1);
|
|
36
|
+
expect(dividers(container)).toHaveLength(0);
|
|
37
|
+
});
|
|
38
|
+
it('renders a divider between panels but not after the last', function () {
|
|
39
|
+
var _renderPanels2 = renderPanels(3),
|
|
40
|
+
container = _renderPanels2.container;
|
|
41
|
+
expect(container.querySelectorAll('.components-panel__body')).toHaveLength(3);
|
|
42
|
+
expect(dividers(container)).toHaveLength(2);
|
|
43
|
+
expect(container.querySelector('.newspack-accordion').lastElementChild).not.toHaveClass('newspack-divider');
|
|
44
|
+
});
|
|
45
|
+
it('renders secondary dividers', function () {
|
|
46
|
+
var _renderPanels3 = renderPanels(2),
|
|
47
|
+
container = _renderPanels3.container;
|
|
48
|
+
expect(dividers(container)[0]).toHaveClass('newspack-divider--variant-secondary');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
describe('Accordion hideSingleTitle', function () {
|
|
52
|
+
it('keeps the title on a lone panel by default', function () {
|
|
53
|
+
renderPanels(1);
|
|
54
|
+
expect(_react.screen.getByRole('button', {
|
|
55
|
+
name: 'Panel 0'
|
|
56
|
+
})).toBeInTheDocument();
|
|
57
|
+
});
|
|
58
|
+
it('drops the title and opens a lone panel when set', function () {
|
|
59
|
+
var _renderPanels4 = renderPanels(1, {
|
|
60
|
+
hideSingleTitle: true
|
|
61
|
+
}),
|
|
62
|
+
container = _renderPanels4.container;
|
|
63
|
+
expect(_react.screen.queryByRole('button', {
|
|
64
|
+
name: 'Panel 0'
|
|
65
|
+
})).not.toBeInTheDocument();
|
|
66
|
+
expect(container.querySelector('.components-panel__body')).toHaveClass('is-opened');
|
|
67
|
+
expect(_react.screen.getByText('content')).toBeInTheDocument();
|
|
68
|
+
});
|
|
69
|
+
it('leaves titles alone when there is more than one panel', function () {
|
|
70
|
+
renderPanels(2, {
|
|
71
|
+
hideSingleTitle: true
|
|
72
|
+
});
|
|
73
|
+
expect(_react.screen.getByRole('button', {
|
|
74
|
+
name: 'Panel 0'
|
|
75
|
+
})).toBeInTheDocument();
|
|
76
|
+
expect(_react.screen.getByRole('button', {
|
|
77
|
+
name: 'Panel 1'
|
|
78
|
+
})).toBeInTheDocument();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -1,31 +1,35 @@
|
|
|
1
|
-
@use "~@wordpress/base-styles/
|
|
1
|
+
@use "~@wordpress/base-styles/mixins" as wp-mixins;
|
|
2
|
+
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
2
3
|
|
|
4
|
+
// Sit flush with the surrounding column: core insets panels horizontally, which
|
|
5
|
+
// would misalign them against the section they belong to.
|
|
3
6
|
.newspack-accordion {
|
|
4
|
-
|
|
7
|
+
.components-panel__body {
|
|
8
|
+
border: 0;
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
10
|
+
> .components-panel__body-title:hover {
|
|
11
|
+
background: none;
|
|
12
|
+
}
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
.components-panel__body.is-opened {
|
|
16
|
+
padding: 0;
|
|
17
|
+
|
|
18
|
+
> .components-panel__body-title {
|
|
19
|
+
margin: 0 0 wp-vars.$grid-unit-30;
|
|
16
20
|
}
|
|
17
21
|
}
|
|
18
|
-
summary {
|
|
19
|
-
padding: 16px 32px;
|
|
20
|
-
display: flex;
|
|
21
|
-
align-items: center;
|
|
22
|
-
justify-content: space-between;
|
|
23
|
-
cursor: pointer;
|
|
24
|
-
font-size: 14px;
|
|
25
|
-
font-weight: bold;
|
|
26
|
-
}
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
.components-panel__body-toggle.components-button {
|
|
24
|
+
@include wp-mixins.heading-large();
|
|
25
|
+
padding: 0;
|
|
26
|
+
|
|
27
|
+
.components-panel__arrow {
|
|
28
|
+
right: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&:focus:not(:focus-visible) {
|
|
32
|
+
box-shadow: none;
|
|
33
|
+
}
|
|
30
34
|
}
|
|
31
35
|
}
|
|
@@ -77,28 +77,6 @@
|
|
|
77
77
|
padding: 0 4px;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
&.mv0 {
|
|
81
|
-
border-left-color: wp-colors.$gray-300;
|
|
82
|
-
border-radius: 0;
|
|
83
|
-
border-right-color: wp-colors.$gray-300;
|
|
84
|
-
|
|
85
|
-
&:first-of-type {
|
|
86
|
-
border-top-color: wp-colors.$gray-300;
|
|
87
|
-
border-top-left-radius: 3px;
|
|
88
|
-
border-top-right-radius: 3px;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
&:last-of-type {
|
|
92
|
-
border-bottom-color: wp-colors.$gray-300;
|
|
93
|
-
border-bottom-left-radius: 3px;
|
|
94
|
-
border-bottom-right-radius: 3px;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
& + & {
|
|
98
|
-
margin-top: -1px;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
80
|
&.newspack-card__is-disabled,
|
|
103
81
|
&.newspack-card__is-primary,
|
|
104
82
|
&.newspack-card__is-secondary,
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports["default"] = void 0;
|
|
7
|
+
var _i18n = require("@wordpress/i18n");
|
|
8
|
+
var _ui = require("@wordpress/ui");
|
|
9
|
+
require("./style.scss");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
/**
|
|
12
|
+
* WordPress dependencies.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Internal dependencies.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Newspack breadcrumb trail.
|
|
21
|
+
*
|
|
22
|
+
* Data-driven: the last item is the current page (the single h1, never a link);
|
|
23
|
+
* every other item renders as a link when it has a `url`, otherwise plain text.
|
|
24
|
+
* A plain `<a href>` drives both full admin URLs and hash routes, so the
|
|
25
|
+
* component needs no router context.
|
|
26
|
+
*
|
|
27
|
+
* @param {Object} props
|
|
28
|
+
* @param {Array} props.items Trail items: `{ label, url? }`.
|
|
29
|
+
* @return {JSX.Element|null} Breadcrumbs component.
|
|
30
|
+
*/var Breadcrumbs = function Breadcrumbs(_ref) {
|
|
31
|
+
var _ref$items = _ref.items,
|
|
32
|
+
items = _ref$items === void 0 ? [] : _ref$items;
|
|
33
|
+
if (!items.length) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
var preceding = items.slice(0, -1);
|
|
37
|
+
var last = items[items.length - 1];
|
|
38
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("nav", {
|
|
39
|
+
"aria-label": (0, _i18n.__)('Breadcrumbs', 'newspack-plugin'),
|
|
40
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ui.Stack, {
|
|
41
|
+
render: /*#__PURE__*/(0, _jsxRuntime.jsx)("ul", {}),
|
|
42
|
+
direction: "row",
|
|
43
|
+
align: "center",
|
|
44
|
+
className: "newspack-breadcrumbs__list",
|
|
45
|
+
children: [preceding.map(function (item, index) {
|
|
46
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("li", {
|
|
47
|
+
children: [item.url ?
|
|
48
|
+
/*#__PURE__*/
|
|
49
|
+
// eslint-disable-next-line jsx-a11y/anchor-has-content -- content is supplied via the Text children through @wordpress/ui's render prop.
|
|
50
|
+
(0, _jsxRuntime.jsx)(_ui.Text, {
|
|
51
|
+
variant: "body-lg",
|
|
52
|
+
render: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Link, {
|
|
53
|
+
tone: "neutral",
|
|
54
|
+
render: /*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
|
|
55
|
+
href: item.url
|
|
56
|
+
})
|
|
57
|
+
}),
|
|
58
|
+
children: item.label
|
|
59
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Text, {
|
|
60
|
+
variant: "body-lg",
|
|
61
|
+
children: item.label
|
|
62
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Text, {
|
|
63
|
+
variant: "body-lg",
|
|
64
|
+
"aria-hidden": "true",
|
|
65
|
+
className: "newspack-breadcrumbs__separator",
|
|
66
|
+
children: "/"
|
|
67
|
+
})]
|
|
68
|
+
}, item.url || index);
|
|
69
|
+
}), last && last.label && /*#__PURE__*/(0, _jsxRuntime.jsx)("li", {
|
|
70
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Text, {
|
|
71
|
+
variant: "heading-lg",
|
|
72
|
+
render: /*#__PURE__*/(0, _jsxRuntime.jsx)("h1", {}),
|
|
73
|
+
className: "newspack-breadcrumbs__current",
|
|
74
|
+
children: last.label
|
|
75
|
+
})
|
|
76
|
+
})]
|
|
77
|
+
})
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
var _default = exports["default"] = Breadcrumbs;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
var _react = require("@testing-library/react");
|
|
5
|
+
var _ = _interopRequireDefault(require("./"));
|
|
6
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
7
|
+
/**
|
|
8
|
+
* External dependencies.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Internal dependencies.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
describe('Breadcrumbs', function () {
|
|
16
|
+
it('renders the last item as the only h1 and never a link', function () {
|
|
17
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
18
|
+
items: [{
|
|
19
|
+
label: 'Newsletters'
|
|
20
|
+
}, {
|
|
21
|
+
label: 'Settings',
|
|
22
|
+
url: '#/x'
|
|
23
|
+
}]
|
|
24
|
+
}));
|
|
25
|
+
var h1s = _react.screen.getAllByRole('heading', {
|
|
26
|
+
level: 1
|
|
27
|
+
});
|
|
28
|
+
expect(h1s).toHaveLength(1);
|
|
29
|
+
expect(h1s[0]).toHaveTextContent('Settings');
|
|
30
|
+
expect(_react.screen.queryByRole('link', {
|
|
31
|
+
name: 'Settings'
|
|
32
|
+
})).not.toBeInTheDocument();
|
|
33
|
+
});
|
|
34
|
+
it('renders a non-last item with a url as a link, without a url as text', function () {
|
|
35
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
36
|
+
items: [{
|
|
37
|
+
label: 'Advertising'
|
|
38
|
+
}, {
|
|
39
|
+
label: 'Sponsors',
|
|
40
|
+
url: '/wp-admin/x'
|
|
41
|
+
}, {
|
|
42
|
+
label: 'All sponsors'
|
|
43
|
+
}]
|
|
44
|
+
}));
|
|
45
|
+
var links = _react.screen.getAllByRole('link');
|
|
46
|
+
expect(links).toHaveLength(1);
|
|
47
|
+
expect(links[0]).toHaveTextContent('Sponsors');
|
|
48
|
+
expect(links[0].getAttribute('href')).toBe('/wp-admin/x');
|
|
49
|
+
expect(_react.screen.getByText('Advertising')).toBeInTheDocument();
|
|
50
|
+
});
|
|
51
|
+
it('does not special-case the first item: it links when it has a url', function () {
|
|
52
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
53
|
+
items: [{
|
|
54
|
+
label: 'Audience',
|
|
55
|
+
url: '#/'
|
|
56
|
+
}, {
|
|
57
|
+
label: 'Donations'
|
|
58
|
+
}]
|
|
59
|
+
}));
|
|
60
|
+
var link = _react.screen.getByRole('link', {
|
|
61
|
+
name: 'Audience'
|
|
62
|
+
});
|
|
63
|
+
expect(link.getAttribute('href')).toBe('#/');
|
|
64
|
+
});
|
|
65
|
+
it('renders a single-item trail as just the h1 with no separator', function () {
|
|
66
|
+
var _render = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
67
|
+
items: [{
|
|
68
|
+
label: 'Dashboard'
|
|
69
|
+
}]
|
|
70
|
+
})),
|
|
71
|
+
container = _render.container;
|
|
72
|
+
expect(_react.screen.getByRole('heading', {
|
|
73
|
+
level: 1
|
|
74
|
+
})).toHaveTextContent('Dashboard');
|
|
75
|
+
expect(container.querySelector('.newspack-breadcrumbs__separator')).toBeNull();
|
|
76
|
+
expect(_react.screen.queryByRole('link')).not.toBeInTheDocument();
|
|
77
|
+
});
|
|
78
|
+
it('renders a "/" separator after each preceding item', function () {
|
|
79
|
+
var _render2 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
80
|
+
items: [{
|
|
81
|
+
label: 'Audience'
|
|
82
|
+
}, {
|
|
83
|
+
label: 'Access control'
|
|
84
|
+
}]
|
|
85
|
+
})),
|
|
86
|
+
container = _render2.container;
|
|
87
|
+
var separators = container.querySelectorAll('.newspack-breadcrumbs__separator');
|
|
88
|
+
expect(separators).toHaveLength(1);
|
|
89
|
+
expect(separators[0]).toHaveTextContent('/');
|
|
90
|
+
expect(separators[0]).toHaveAttribute('aria-hidden', 'true');
|
|
91
|
+
});
|
|
92
|
+
it('renders no heading when the last item has no label', function () {
|
|
93
|
+
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
94
|
+
items: [{
|
|
95
|
+
label: undefined
|
|
96
|
+
}]
|
|
97
|
+
}));
|
|
98
|
+
expect(_react.screen.queryByRole('heading', {
|
|
99
|
+
level: 1
|
|
100
|
+
})).not.toBeInTheDocument();
|
|
101
|
+
});
|
|
102
|
+
it('renders nothing when there are no items', function () {
|
|
103
|
+
var _render3 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
|
|
104
|
+
items: []
|
|
105
|
+
})),
|
|
106
|
+
container = _render3.container;
|
|
107
|
+
expect(container.querySelector('nav')).not.toBeInTheDocument();
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
2
|
+
|
|
3
|
+
.newspack-breadcrumbs__list {
|
|
4
|
+
list-style: none;
|
|
5
|
+
margin: 0;
|
|
6
|
+
padding: 0;
|
|
7
|
+
|
|
8
|
+
> li {
|
|
9
|
+
flex-shrink: 0;
|
|
10
|
+
margin: 0;
|
|
11
|
+
|
|
12
|
+
a {
|
|
13
|
+
color: wp-colors.$gray-900;
|
|
14
|
+
|
|
15
|
+
&:hover,
|
|
16
|
+
&:focus,
|
|
17
|
+
&:active {
|
|
18
|
+
color: wp-colors.$gray-900;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
> li:last-child {
|
|
24
|
+
flex-shrink: 1;
|
|
25
|
+
min-width: 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.newspack-breadcrumbs__separator {
|
|
30
|
+
color: var(--wpds-color-stroke-surface-neutral, #dbdbdb);
|
|
31
|
+
margin: 0 var(--wpds-dimension-gap-sm, 8px);
|
|
32
|
+
user-select: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.newspack-breadcrumbs__list h1.newspack-breadcrumbs__current {
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
text-overflow: ellipsis;
|
|
38
|
+
white-space: nowrap;
|
|
39
|
+
padding: 0;
|
|
40
|
+
line-height: normal;
|
|
41
|
+
}
|
|
@@ -13,7 +13,7 @@ var _icons = require("@wordpress/icons");
|
|
|
13
13
|
require("./style-core.scss");
|
|
14
14
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
15
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
|
-
var _excluded = ["actions", "actionType", "as", "buttonsCard", "className", "footer", "header", "headerAction", "headerStyle", "childrenStyle", "footerStyle", "disabled", "icon", "iconBackgroundColor", "isActive", "isDraggable", "isFirstTarget", "isLastTarget", "isNarrow", "isSmall", "dragIndex", "onDragCallback", "onToggle", "onHeaderClick", "noBorder", "noMargin", "children", "hasGreyHeader", "hasHeaderBorder"];
|
|
16
|
+
var _excluded = ["actions", "actionType", "as", "buttonsCard", "className", "footer", "header", "headerAction", "headerStyle", "childrenStyle", "footerStyle", "disabled", "icon", "iconElement", "iconBackgroundColor", "isActive", "isDraggable", "isFirstTarget", "isLastTarget", "isNarrow", "isSmall", "dragIndex", "onDragCallback", "onToggle", "onHeaderClick", "noBorder", "noMargin", "children", "hasGreyHeader", "hasHeaderBorder"];
|
|
17
17
|
/**
|
|
18
18
|
* Card using WP Core's Card component.
|
|
19
19
|
* https://wordpress.github.io/gutenberg/?path=/docs/components-card--docs
|
|
@@ -43,6 +43,7 @@ var CoreCard = function CoreCard(_ref) {
|
|
|
43
43
|
footerStyle = _ref.footerStyle,
|
|
44
44
|
disabled = _ref.disabled,
|
|
45
45
|
icon = _ref.icon,
|
|
46
|
+
iconElement = _ref.iconElement,
|
|
46
47
|
iconBackgroundColor = _ref.iconBackgroundColor,
|
|
47
48
|
isActive = _ref.isActive,
|
|
48
49
|
isDraggable = _ref.isDraggable,
|
|
@@ -64,7 +65,7 @@ var CoreCard = function CoreCard(_ref) {
|
|
|
64
65
|
_ref$hasHeaderBorder = _ref.hasHeaderBorder,
|
|
65
66
|
hasHeaderBorder = _ref$hasHeaderBorder === void 0 ? true : _ref$hasHeaderBorder,
|
|
66
67
|
otherProps = (0, _objectWithoutProperties2["default"])(_ref, _excluded);
|
|
67
|
-
var classes = (0, _classnames["default"])('newspack-card--core', className, (buttonsCard || as === 'a') && 'newspack-card--core__buttons-card', (actions === null || actions === void 0 ? void 0 : actions.length) > 0 && 'newspack-card--core__header--has-actions', isDraggable && 'newspack-card--core__is-draggable', isNarrow && 'newspack-card--core__is-narrow', isSmall && 'newspack-card--core__is-small', icon && 'newspack-card--core__has-icon', iconBackgroundColor && 'newspack-card--core__has-icon-background-color', isActive && 'newspack-card--core__is-active', disabled && 'newspack-card--core__is-disabled', children && 'newspack-card--core__has-children', noMargin && 'newspack-card--core__no-margin', hasGreyHeader && 'newspack-card--core__has-grey-header');
|
|
68
|
+
var classes = (0, _classnames["default"])('newspack-card--core', className, (buttonsCard || as === 'a') && 'newspack-card--core__buttons-card', (actions === null || actions === void 0 ? void 0 : actions.length) > 0 && 'newspack-card--core__header--has-actions', isDraggable && 'newspack-card--core__is-draggable', isNarrow && 'newspack-card--core__is-narrow', isSmall && 'newspack-card--core__is-small', (icon || iconElement) && 'newspack-card--core__has-icon', iconBackgroundColor && 'newspack-card--core__has-icon-background-color', isActive && 'newspack-card--core__is-active', disabled && 'newspack-card--core__is-disabled', children && 'newspack-card--core__has-children', noMargin && 'newspack-card--core__no-margin', hasGreyHeader && 'newspack-card--core__has-grey-header');
|
|
68
69
|
var sizeProps = isSmall ? 'small' : otherProps.size;
|
|
69
70
|
if (buttonsCard || as === 'a') {
|
|
70
71
|
if (!isSmall) {
|
|
@@ -86,7 +87,7 @@ var CoreCard = function CoreCard(_ref) {
|
|
|
86
87
|
as: as,
|
|
87
88
|
className: classes
|
|
88
89
|
}, otherProps), {}, {
|
|
89
|
-
children: [(header || icon) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.CardHeader, {
|
|
90
|
+
children: [(header || icon || iconElement) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.CardHeader, {
|
|
90
91
|
as: headerIsButton ? 'button' : undefined,
|
|
91
92
|
className: (0, _classnames["default"])('newspack-card--core__header', isDraggable && 'newspack-card--core__header--is-draggable', !hasHeaderBorder && 'newspack-card--core__header--no-border'),
|
|
92
93
|
style: headerStyle,
|
|
@@ -122,7 +123,10 @@ var CoreCard = function CoreCard(_ref) {
|
|
|
122
123
|
size: "small"
|
|
123
124
|
})]
|
|
124
125
|
})]
|
|
125
|
-
}),
|
|
126
|
+
}), iconElement ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
127
|
+
className: "newspack-card--core__icon-slot",
|
|
128
|
+
children: iconElement
|
|
129
|
+
}) : icon && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
126
130
|
className: "newspack-card--core__icon",
|
|
127
131
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.Icon, {
|
|
128
132
|
icon: icon,
|
package/dist/cjs/card/index.js
CHANGED
|
@@ -81,7 +81,7 @@ var Card = /*#__PURE__*/function (_Component) {
|
|
|
81
81
|
}, otherProps), __experimentalCoreProps);
|
|
82
82
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_coreCard["default"], _objectSpread({}, props));
|
|
83
83
|
}
|
|
84
|
-
var classes = (0, _classnames["default"])('newspack-card', className,
|
|
84
|
+
var classes = (0, _classnames["default"])('newspack-card', className, headerActions && 'newspack-card__header-actions', isMedium && 'newspack-card__is-medium', isNarrow && 'newspack-card__is-narrow', isSmall && 'newspack-card__is-small', isWhite && 'newspack-card__is-white', noBorder && 'newspack-card__no-border');
|
|
85
85
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", _objectSpread({
|
|
86
86
|
className: classes
|
|
87
87
|
}, otherProps));
|
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
svg {
|
|
15
15
|
transition: fill 125ms ease-in-out;
|
|
16
16
|
}
|
|
17
|
+
// Slot for a pre-rendered icon element that owns its own badge.
|
|
18
|
+
&__icon-slot {
|
|
19
|
+
align-items: center;
|
|
20
|
+
display: flex;
|
|
21
|
+
}
|
|
17
22
|
&__icon {
|
|
18
23
|
border-radius: wp-vars.$radius-round;
|
|
19
24
|
display: grid;
|
|
@@ -149,6 +154,15 @@
|
|
|
149
154
|
border: none;
|
|
150
155
|
cursor: pointer;
|
|
151
156
|
text-align: left;
|
|
157
|
+
|
|
158
|
+
// The header becomes a real button (headerIsButton) with no border, so
|
|
159
|
+
// give keyboard focus an explicit on-brand ring. Inset so it isn't clipped
|
|
160
|
+
// by the card; the transparent outline keeps it visible under Windows High
|
|
161
|
+
// Contrast / forced-colors mode.
|
|
162
|
+
&:focus-visible {
|
|
163
|
+
box-shadow: inset 0 0 0 2px var(--wp-admin-theme-color);
|
|
164
|
+
outline: 2px solid transparent;
|
|
165
|
+
}
|
|
152
166
|
}
|
|
153
167
|
&__header-content {
|
|
154
168
|
display: grid;
|
package/dist/cjs/card/style.scss
CHANGED