newspack-components 4.7.0 → 4.8.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.
Files changed (251) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/DEVELOPMENT.md +42 -21
  3. package/dist/cjs/_mixins.scss +13 -0
  4. package/dist/cjs/_variables.scss +12 -0
  5. package/dist/cjs/action-card/index.js +18 -10
  6. package/dist/cjs/action-card/index.test.js +91 -0
  7. package/dist/cjs/action-card/style.scss +2 -40
  8. package/dist/cjs/button/index.js +8 -3
  9. package/dist/cjs/button/index.test.js +61 -5
  10. package/dist/cjs/card/core-card.js +0 -2
  11. package/dist/cjs/card/style-core.scss +7 -5
  12. package/dist/cjs/card-feature/index.js +75 -61
  13. package/dist/cjs/card-feature/index.test.js +396 -54
  14. package/dist/cjs/card-feature/style.scss +20 -31
  15. package/dist/cjs/card-form/index.js +5 -5
  16. package/dist/cjs/card-sortable-list/index.js +5 -3
  17. package/dist/cjs/card-sortable-list/index.test.js +50 -0
  18. package/dist/cjs/collapsible-group/context.js +19 -0
  19. package/dist/cjs/collapsible-group/index.js +24 -0
  20. package/dist/cjs/collapsible-group/index.test.js +215 -0
  21. package/dist/cjs/collapsible-group/item.js +61 -0
  22. package/dist/cjs/collapsible-group/root.js +62 -0
  23. package/dist/cjs/collapsible-group/style.scss +47 -0
  24. package/dist/cjs/collapsible-group/types.js +5 -0
  25. package/dist/cjs/empty-state/actions.js +45 -0
  26. package/dist/cjs/empty-state/context.js +41 -0
  27. package/dist/cjs/empty-state/header.js +66 -0
  28. package/dist/cjs/empty-state/index.js +31 -0
  29. package/dist/cjs/empty-state/index.test.js +303 -0
  30. package/dist/cjs/empty-state/root.js +56 -0
  31. package/dist/cjs/empty-state/style.scss +51 -0
  32. package/dist/cjs/empty-state/types.js +5 -0
  33. package/dist/cjs/index.js +34 -20
  34. package/dist/cjs/info-button/index.js +59 -43
  35. package/dist/cjs/info-button/index.test.js +199 -0
  36. package/dist/cjs/info-button/style.scss +41 -9
  37. package/dist/cjs/modal/style.scss +12 -12
  38. package/dist/cjs/newspack-icon/style.scss +4 -4
  39. package/dist/cjs/notice/style.scss +3 -3
  40. package/dist/cjs/page/style.scss +16 -16
  41. package/dist/cjs/plugin-installer/index.js +5 -9
  42. package/dist/cjs/plugin-installer/style.scss +3 -14
  43. package/dist/cjs/section-header/index.js +31 -18
  44. package/dist/cjs/section-header/index.test.js +40 -0
  45. package/dist/cjs/section-header/style.scss +22 -6
  46. package/dist/cjs/settings/DateRangeSetting.js +309 -0
  47. package/dist/cjs/settings/SettingsSection.js +19 -5
  48. package/dist/cjs/settings/SettingsSection.test.js +49 -0
  49. package/dist/cjs/settings/index.js +3 -1
  50. package/dist/cjs/settings/style.scss +40 -7
  51. package/dist/cjs/stat-card/body.js +41 -0
  52. package/dist/cjs/stat-card/constants.js +11 -0
  53. package/dist/cjs/stat-card/context.js +54 -0
  54. package/dist/cjs/stat-card/delta.js +91 -0
  55. package/dist/cjs/stat-card/footer.js +72 -0
  56. package/dist/cjs/stat-card/index.js +47 -0
  57. package/dist/cjs/stat-card/index.test.js +938 -0
  58. package/dist/cjs/stat-card/label.js +66 -0
  59. package/dist/cjs/stat-card/root.js +69 -0
  60. package/dist/cjs/stat-card/secondary.js +38 -0
  61. package/dist/cjs/stat-card/style.scss +89 -0
  62. package/dist/cjs/stat-card/types.js +5 -0
  63. package/dist/cjs/stat-card/value.js +78 -0
  64. package/dist/cjs/status-indicator/index.js +66 -0
  65. package/dist/cjs/status-indicator/index.test.js +101 -0
  66. package/dist/cjs/status-indicator/statuses.js +39 -0
  67. package/dist/cjs/status-indicator/style.scss +9 -0
  68. package/dist/cjs/status-indicator/types.js +5 -0
  69. package/dist/cjs/style.scss +9 -9
  70. package/dist/cjs/tabbed-navigation/style.scss +6 -4
  71. package/dist/cjs/types.js +5 -0
  72. package/dist/cjs/web-preview/style.scss +11 -11
  73. package/dist/cjs/with-wizard/style.scss +10 -10
  74. package/dist/cjs/with-wizard-screen/style.scss +9 -9
  75. package/dist/cjs/wizard/index.js +33 -4
  76. package/dist/cjs/wizard/store/index.js +23 -1
  77. package/dist/esm/_mixins.scss +13 -0
  78. package/dist/esm/_variables.scss +12 -0
  79. package/dist/esm/action-card/index.js +18 -10
  80. package/dist/esm/action-card/index.test.js +89 -0
  81. package/dist/esm/action-card/style.scss +2 -40
  82. package/dist/esm/button/index.js +9 -4
  83. package/dist/esm/button/index.test.js +63 -5
  84. package/dist/esm/card/core-card.js +0 -2
  85. package/dist/esm/card/style-core.scss +7 -5
  86. package/dist/esm/card-feature/index.js +78 -62
  87. package/dist/esm/card-feature/index.test.js +397 -55
  88. package/dist/esm/card-feature/style.scss +20 -31
  89. package/dist/esm/card-form/index.js +5 -5
  90. package/dist/esm/card-sortable-list/index.js +6 -4
  91. package/dist/esm/card-sortable-list/index.test.js +46 -0
  92. package/dist/esm/collapsible-group/context.js +13 -0
  93. package/dist/esm/collapsible-group/index.js +17 -0
  94. package/dist/esm/collapsible-group/index.test.js +215 -0
  95. package/dist/esm/collapsible-group/item.js +53 -0
  96. package/dist/esm/collapsible-group/root.js +54 -0
  97. package/dist/esm/collapsible-group/style.scss +47 -0
  98. package/dist/esm/collapsible-group/types.js +1 -0
  99. package/dist/esm/empty-state/actions.js +37 -0
  100. package/dist/esm/empty-state/context.js +35 -0
  101. package/dist/esm/empty-state/header.js +58 -0
  102. package/dist/esm/empty-state/index.js +23 -0
  103. package/dist/esm/empty-state/index.test.js +299 -0
  104. package/dist/esm/empty-state/root.js +56 -0
  105. package/dist/esm/empty-state/style.scss +51 -0
  106. package/dist/esm/empty-state/types.js +1 -0
  107. package/dist/esm/index.js +4 -2
  108. package/dist/esm/info-button/index.js +54 -43
  109. package/dist/esm/info-button/index.test.js +195 -0
  110. package/dist/esm/info-button/style.scss +41 -9
  111. package/dist/esm/modal/style.scss +12 -12
  112. package/dist/esm/newspack-icon/style.scss +4 -4
  113. package/dist/esm/notice/style.scss +3 -3
  114. package/dist/esm/page/style.scss +16 -16
  115. package/dist/esm/plugin-installer/index.js +5 -9
  116. package/dist/esm/plugin-installer/style.scss +3 -14
  117. package/dist/esm/section-header/index.js +27 -14
  118. package/dist/esm/section-header/index.test.js +36 -0
  119. package/dist/esm/section-header/style.scss +22 -6
  120. package/dist/esm/settings/DateRangeSetting.js +304 -0
  121. package/dist/esm/settings/SettingsSection.js +16 -3
  122. package/dist/esm/settings/SettingsSection.test.js +45 -0
  123. package/dist/esm/settings/index.js +3 -1
  124. package/dist/esm/settings/style.scss +40 -7
  125. package/dist/esm/stat-card/body.js +36 -0
  126. package/dist/esm/stat-card/constants.js +5 -0
  127. package/dist/esm/stat-card/context.js +48 -0
  128. package/dist/esm/stat-card/delta.js +86 -0
  129. package/dist/esm/stat-card/footer.js +67 -0
  130. package/dist/esm/stat-card/index.js +33 -0
  131. package/dist/esm/stat-card/index.test.js +939 -0
  132. package/dist/esm/stat-card/label.js +61 -0
  133. package/dist/esm/stat-card/root.js +64 -0
  134. package/dist/esm/stat-card/secondary.js +33 -0
  135. package/dist/esm/stat-card/style.scss +89 -0
  136. package/dist/esm/stat-card/types.js +1 -0
  137. package/dist/esm/stat-card/value.js +73 -0
  138. package/dist/esm/status-indicator/index.js +52 -0
  139. package/dist/esm/status-indicator/index.test.js +96 -0
  140. package/dist/esm/status-indicator/statuses.js +33 -0
  141. package/dist/esm/status-indicator/style.scss +9 -0
  142. package/dist/esm/status-indicator/types.js +1 -0
  143. package/dist/esm/style.scss +9 -9
  144. package/dist/esm/tabbed-navigation/style.scss +6 -4
  145. package/dist/esm/types.js +1 -0
  146. package/dist/esm/web-preview/style.scss +11 -11
  147. package/dist/esm/with-wizard/style.scss +10 -10
  148. package/dist/esm/with-wizard-screen/style.scss +9 -9
  149. package/dist/esm/wizard/index.js +38 -7
  150. package/dist/esm/wizard/store/index.js +23 -1
  151. package/package.json +1 -1
  152. package/src/_mixins.scss +13 -0
  153. package/src/_variables.scss +12 -0
  154. package/src/action-card/action-card.d.ts +3 -2
  155. package/src/action-card/index.js +12 -12
  156. package/src/action-card/index.test.js +56 -0
  157. package/src/action-card/style.scss +2 -40
  158. package/src/button/index.test.js +52 -5
  159. package/src/button/index.tsx +9 -4
  160. package/src/card/core-card.js +0 -2
  161. package/src/card/style-core.scss +7 -5
  162. package/src/card-feature/README.md +68 -27
  163. package/src/card-feature/index.test.js +242 -27
  164. package/src/card-feature/index.tsx +77 -67
  165. package/src/card-feature/style.scss +20 -31
  166. package/src/card-form/README.md +10 -10
  167. package/src/card-form/index.tsx +4 -8
  168. package/src/card-sortable-list/README.md +4 -5
  169. package/src/card-sortable-list/index.test.js +29 -0
  170. package/src/card-sortable-list/index.tsx +7 -4
  171. package/src/collapsible-group/README.md +50 -0
  172. package/src/collapsible-group/context.ts +13 -0
  173. package/src/collapsible-group/index.test.js +168 -0
  174. package/src/collapsible-group/index.tsx +17 -0
  175. package/src/collapsible-group/item.tsx +42 -0
  176. package/src/collapsible-group/root.tsx +42 -0
  177. package/src/collapsible-group/style.scss +47 -0
  178. package/src/collapsible-group/types.ts +22 -0
  179. package/src/drawer/README.md +2 -2
  180. package/src/empty-state/README.md +165 -0
  181. package/src/empty-state/actions.tsx +37 -0
  182. package/src/empty-state/context.ts +40 -0
  183. package/src/empty-state/header.tsx +48 -0
  184. package/src/empty-state/index.test.js +247 -0
  185. package/src/empty-state/index.tsx +22 -0
  186. package/src/empty-state/root.tsx +39 -0
  187. package/src/empty-state/style.scss +51 -0
  188. package/src/empty-state/types.ts +33 -0
  189. package/src/index.js +4 -2
  190. package/src/info-button/README.md +115 -0
  191. package/src/info-button/index.test.js +163 -0
  192. package/src/info-button/index.tsx +64 -0
  193. package/src/info-button/style.scss +41 -9
  194. package/src/modal/style.scss +12 -12
  195. package/src/newspack-icon/style.scss +4 -4
  196. package/src/notice/style.scss +3 -3
  197. package/src/page/style.scss +16 -16
  198. package/src/plugin-installer/index.js +3 -9
  199. package/src/plugin-installer/style.scss +3 -14
  200. package/src/section-header/index.js +27 -14
  201. package/src/section-header/index.test.js +28 -0
  202. package/src/section-header/style.scss +22 -6
  203. package/src/settings/DateRangeSetting.js +266 -0
  204. package/src/settings/SettingsSection.js +24 -4
  205. package/src/settings/SettingsSection.test.js +45 -0
  206. package/src/settings/index.js +2 -0
  207. package/src/settings/style.scss +40 -7
  208. package/src/stat-card/README.md +434 -0
  209. package/src/stat-card/body.tsx +28 -0
  210. package/src/stat-card/constants.ts +5 -0
  211. package/src/stat-card/context.ts +53 -0
  212. package/src/stat-card/delta.tsx +88 -0
  213. package/src/stat-card/footer.tsx +68 -0
  214. package/src/stat-card/index.test.js +818 -0
  215. package/src/stat-card/index.tsx +48 -0
  216. package/src/stat-card/label.tsx +61 -0
  217. package/src/stat-card/root.tsx +40 -0
  218. package/src/stat-card/secondary.tsx +27 -0
  219. package/src/stat-card/style.scss +89 -0
  220. package/src/stat-card/types.ts +84 -0
  221. package/src/stat-card/value.tsx +72 -0
  222. package/src/status-indicator/README.md +123 -0
  223. package/src/status-indicator/index.test.js +70 -0
  224. package/src/status-indicator/index.tsx +39 -0
  225. package/src/status-indicator/statuses.ts +35 -0
  226. package/src/status-indicator/style.scss +9 -0
  227. package/src/status-indicator/types.ts +28 -0
  228. package/src/style.scss +9 -9
  229. package/src/tabbed-navigation/style.scss +6 -4
  230. package/src/types.ts +25 -0
  231. package/src/web-preview/style.scss +11 -11
  232. package/src/with-wizard/style.scss +10 -10
  233. package/src/with-wizard-screen/style.scss +9 -9
  234. package/src/wizard/index.js +49 -7
  235. package/src/wizard/store/index.js +26 -1
  236. package/dist/cjs/accordion/index.js +0 -72
  237. package/dist/cjs/accordion/index.test.js +0 -80
  238. package/dist/cjs/accordion/style.scss +0 -35
  239. package/dist/cjs/badge/index.js +0 -32
  240. package/dist/cjs/badge/style.scss +0 -36
  241. package/dist/esm/accordion/index.js +0 -63
  242. package/dist/esm/accordion/index.test.js +0 -79
  243. package/dist/esm/accordion/style.scss +0 -35
  244. package/dist/esm/badge/index.js +0 -24
  245. package/dist/esm/badge/style.scss +0 -36
  246. package/src/accordion/index.js +0 -46
  247. package/src/accordion/index.test.js +0 -62
  248. package/src/accordion/style.scss +0 -35
  249. package/src/badge/index.tsx +0 -26
  250. package/src/badge/style.scss +0 -36
  251. package/src/info-button/index.js +0 -38
@@ -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 _ui = require("@wordpress/ui");
9
+ var _classnames = _interopRequireDefault(require("classnames"));
10
+ var _context = require("./context");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ /**
13
+ * WordPress dependencies.
14
+ */
15
+
16
+ /**
17
+ * External dependencies.
18
+ */
19
+
20
+ /**
21
+ * Internal dependencies.
22
+ */
23
+
24
+ var Actions = function Actions(_ref) {
25
+ var _ref$orientation = _ref.orientation,
26
+ orientation = _ref$orientation === void 0 ? 'row' : _ref$orientation,
27
+ _ref$gap = _ref.gap,
28
+ gap = _ref$gap === void 0 ? 'sm' : _ref$gap,
29
+ className = _ref.className,
30
+ children = _ref.children;
31
+ (0, _context.useEmptyStateInvariant)();
32
+ var isColumn = orientation === 'column';
33
+
34
+ // Rows wrap: the empty state only gets half the grid above 1054px.
35
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Stack, {
36
+ direction: isColumn ? 'column' : 'row',
37
+ align: "center",
38
+ justify: "center",
39
+ gap: gap,
40
+ wrap: isColumn ? undefined : 'wrap',
41
+ className: (0, _classnames["default"])('newspack-empty-state__actions', className),
42
+ children: children
43
+ });
44
+ };
45
+ var _default = exports["default"] = Actions;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useEmptyStateInvariant = exports.useEmptyStateContext = exports.EmptyStateContext = void 0;
7
+ var _element = require("@wordpress/element");
8
+ /**
9
+ * WordPress dependencies.
10
+ */
11
+
12
+ /**
13
+ * Internal dependencies.
14
+ */
15
+
16
+ var EmptyStateContext = exports.EmptyStateContext = (0, _element.createContext)(null);
17
+ var FALLBACK_CONTEXT = {
18
+ size: 'default'
19
+ };
20
+ var useEmptyStateContext = exports.useEmptyStateContext = function useEmptyStateContext() {
21
+ var context = (0, _element.useContext)(EmptyStateContext);
22
+ if (!context && process.env.NODE_ENV !== 'production') {
23
+ throw new Error('EmptyState subcomponents must be rendered inside EmptyState.Root.');
24
+ }
25
+ return context !== null && context !== void 0 ? context : FALLBACK_CONTEXT;
26
+ };
27
+
28
+ /**
29
+ * Assert placement inside a `Root` without depending on the value.
30
+ *
31
+ * For subcomponents that read nothing from context. Both hooks throw in
32
+ * development so the mistake surfaces while it is cheap, and neither throws in
33
+ * production, because a stray subcomponent should not blank an admin screen
34
+ * over a layout hint.
35
+ */
36
+ var useEmptyStateInvariant = exports.useEmptyStateInvariant = function useEmptyStateInvariant() {
37
+ var context = (0, _element.useContext)(EmptyStateContext);
38
+ if (!context && process.env.NODE_ENV !== 'production') {
39
+ throw new Error('EmptyState subcomponents must be rendered inside EmptyState.Root.');
40
+ }
41
+ };
@@ -0,0 +1,66 @@
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 _ui = require("@wordpress/ui");
10
+ var _classnames = _interopRequireDefault(require("classnames"));
11
+ var _context = require("./context");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ /**
14
+ * WordPress dependencies.
15
+ */
16
+
17
+ /**
18
+ * External dependencies.
19
+ */
20
+
21
+ /**
22
+ * Internal dependencies.
23
+ */
24
+
25
+ var Header = function Header(_ref) {
26
+ var icon = _ref.icon,
27
+ title = _ref.title,
28
+ description = _ref.description,
29
+ heading = _ref.heading,
30
+ className = _ref.className;
31
+ var _useEmptyStateContext = (0, _context.useEmptyStateContext)(),
32
+ size = _useEmptyStateContext.size;
33
+ var isSmall = size === 'small';
34
+
35
+ // Heading level is a document-outline concern, so the size only sets a default.
36
+ var level = heading !== null && heading !== void 0 ? heading : isSmall ? 3 : 2;
37
+ var HeadingTag = "h".concat(level);
38
+
39
+ // Two stacks so each gap belongs to exactly one of them: the inner one spaces the
40
+ // icon from the title, the outer one the title from the description.
41
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ui.Stack, {
42
+ direction: "column",
43
+ align: "center",
44
+ gap: "sm",
45
+ className: (0, _classnames["default"])('newspack-empty-state__header', isSmall && 'newspack-empty-state__header--small', className),
46
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_ui.Stack, {
47
+ direction: "column",
48
+ align: "center",
49
+ gap: isSmall ? 'md' : 'lg',
50
+ children: [icon && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
51
+ className: "newspack-empty-state__icon",
52
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.Icon, {
53
+ icon: icon,
54
+ size: isSmall ? 24 : 48
55
+ })
56
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(HeadingTag, {
57
+ className: "newspack-empty-state__title",
58
+ children: title
59
+ })]
60
+ }), description && /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
61
+ className: "newspack-empty-state__description",
62
+ children: description
63
+ })]
64
+ });
65
+ };
66
+ var _default = exports["default"] = Header;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports["default"] = exports.EmptyState = void 0;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _actions = _interopRequireDefault(require("./actions"));
10
+ var _header = _interopRequireDefault(require("./header"));
11
+ var _root = _interopRequireDefault(require("./root"));
12
+ /**
13
+ * EmptyState
14
+ */
15
+
16
+ /**
17
+ * Internal dependencies.
18
+ */
19
+
20
+ var EmptyState = exports.EmptyState = {
21
+ Root: _root["default"],
22
+ Header: _header["default"],
23
+ Actions: _actions["default"]
24
+ };
25
+ Object.entries(EmptyState).forEach(function (_ref) {
26
+ var _ref2 = (0, _slicedToArray2["default"])(_ref, 2),
27
+ name = _ref2[0],
28
+ part = _ref2[1];
29
+ part.displayName = "EmptyState.".concat(name);
30
+ });
31
+ var _default = exports["default"] = EmptyState;
@@ -0,0 +1,303 @@
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('EmptyState.Root', function () {
16
+ it('renders the four-column grid spine', function () {
17
+ var _render = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
18
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
19
+ children: "body"
20
+ })
21
+ })),
22
+ container = _render.container;
23
+ var grid = container.querySelector('.newspack-empty-state');
24
+ expect(grid).toHaveClass('newspack-grid');
25
+ expect(grid).toHaveClass('newspack-grid__columns-4');
26
+ expect(grid).toHaveClass('newspack-grid--no-margin');
27
+ });
28
+
29
+ // grid/style.scss matches on these attributes, so they are a contract.
30
+ it('gives the inner stack the data attributes the Grid stylesheet matches on', function () {
31
+ var _render2 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
32
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
33
+ children: "body"
34
+ })
35
+ })),
36
+ container = _render2.container;
37
+ var stack = container.querySelector('.newspack-empty-state').firstElementChild;
38
+ expect(stack).toHaveAttribute('data-start', '2');
39
+ expect(stack).toHaveAttribute('data-end', '4');
40
+ });
41
+
42
+ // The width cap hangs off this class, so losing it silently widens the block.
43
+ it('carries the stack class hook', function () {
44
+ var _render3 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
45
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
46
+ children: "body"
47
+ })
48
+ })),
49
+ container = _render3.container;
50
+ var stack = container.querySelector('.newspack-empty-state').firstElementChild;
51
+ expect(stack).toHaveClass('newspack-empty-state__stack');
52
+ expect(stack).toHaveStyle({
53
+ gap: 'var(--wpds-dimension-gap-2xl, 32px)'
54
+ });
55
+ });
56
+
57
+ // Consumers key `:has()` selectors off this class, so losing it changes their
58
+ // layout without failing anything.
59
+ it('merges className onto the grid', function () {
60
+ var _render4 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
61
+ className: "consumer-empty-state",
62
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
63
+ children: "body"
64
+ })
65
+ })),
66
+ container = _render4.container;
67
+ expect(container.querySelector('.newspack-empty-state')).toHaveClass('consumer-empty-state');
68
+ });
69
+
70
+ // Elements, not a bare string: the stack keeps a lone string but drops one sitting
71
+ // beside an element.
72
+ it('renders its children', function () {
73
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
74
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
75
+ children: "body"
76
+ })
77
+ }));
78
+ expect(_react.screen.getByText('body')).toBeInTheDocument();
79
+ });
80
+ });
81
+ describe('EmptyState.Header', function () {
82
+ it('renders the title and description in the header', function () {
83
+ var _render5 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
84
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
85
+ title: "Get started with newsletters",
86
+ description: "Compose and send."
87
+ })
88
+ })),
89
+ container = _render5.container;
90
+ expect(container.querySelector('.newspack-empty-state__title')).toHaveTextContent('Get started with newsletters');
91
+ expect(container.querySelector('.newspack-empty-state__description')).toHaveTextContent('Compose and send.');
92
+ });
93
+
94
+ // Spacing comes from the stacks, so a margin creeping back onto the heading or
95
+ // paragraph would silently widen every gap.
96
+ it('spaces the header from its stacks rather than from margins', function () {
97
+ var _render6 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
98
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
99
+ title: "Get started with newsletters",
100
+ description: "Compose and send."
101
+ })
102
+ })),
103
+ container = _render6.container;
104
+ var header = container.querySelector('.newspack-empty-state__header');
105
+ expect(header).toHaveStyle({
106
+ flexDirection: 'column',
107
+ alignItems: 'center',
108
+ gap: 'var(--wpds-dimension-gap-sm, 8px)'
109
+ });
110
+ expect(header.firstElementChild).toHaveStyle({
111
+ flexDirection: 'column',
112
+ alignItems: 'center',
113
+ gap: 'var(--wpds-dimension-gap-lg, 16px)'
114
+ });
115
+ });
116
+ it('wraps the icon in the disc', function () {
117
+ var _render7 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
118
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
119
+ title: "Get started with newsletters",
120
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
121
+ })
122
+ })),
123
+ container = _render7.container;
124
+ expect(container.querySelector('.newspack-empty-state__icon svg')).toBeInTheDocument();
125
+ });
126
+ 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, {
128
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
129
+ title: "Get started with newsletters"
130
+ })
131
+ })),
132
+ container = _render8.container;
133
+ expect(container.querySelector('.newspack-empty-state__description')).not.toBeInTheDocument();
134
+ expect(container.querySelector('.newspack-empty-state__icon')).not.toBeInTheDocument();
135
+ });
136
+ 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, {
138
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
139
+ title: "Get started with newsletters",
140
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
141
+ })
142
+ })),
143
+ container = _render9.container;
144
+ expect(_react.screen.getByRole('heading', {
145
+ level: 2,
146
+ name: 'Get started with newsletters'
147
+ })).toBeInTheDocument();
148
+ expect(container.querySelector('.newspack-empty-state__header--small')).not.toBeInTheDocument();
149
+ expect(container.querySelector('.newspack-empty-state__icon svg')).toHaveAttribute('width', '48');
150
+ });
151
+ 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, {
153
+ size: "small",
154
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
155
+ title: "No products match this rule",
156
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
157
+ })
158
+ })),
159
+ container = _render0.container;
160
+ expect(container.querySelector('.newspack-empty-state__header--small')).toBeInTheDocument();
161
+ expect(_react.screen.getByRole('heading', {
162
+ level: 3,
163
+ name: 'No products match this rule'
164
+ })).toBeInTheDocument();
165
+ expect(container.querySelector('.newspack-empty-state__icon svg')).toHaveAttribute('width', '24');
166
+ expect(container.querySelector('.newspack-empty-state__header').firstElementChild).toHaveStyle({
167
+ gap: 'var(--wpds-dimension-gap-md, 12px)'
168
+ });
169
+ });
170
+ it('lets heading override the level the size implies', function () {
171
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
172
+ size: "small",
173
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
174
+ title: "No products match this rule",
175
+ heading: 1
176
+ })
177
+ }));
178
+ expect(_react.screen.getByRole('heading', {
179
+ level: 1,
180
+ name: 'No products match this rule'
181
+ })).toBeInTheDocument();
182
+ });
183
+ it('carries its own class hook alongside any className', function () {
184
+ var _render1 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
185
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
186
+ title: "Get started with newsletters",
187
+ className: "consumer-header"
188
+ })
189
+ })),
190
+ container = _render1.container;
191
+ var header = container.querySelector('.newspack-empty-state__header');
192
+ expect(header).toBeInTheDocument();
193
+ expect(header).toHaveClass('consumer-header');
194
+ });
195
+ it('throws outside Root in development', function () {
196
+ var consoleError = jest.spyOn(console, 'error').mockImplementation(function () {});
197
+ try {
198
+ expect(function () {
199
+ return (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
200
+ title: "Orphan"
201
+ }));
202
+ }).toThrow('EmptyState subcomponents must be rendered inside EmptyState.Root.');
203
+ } finally {
204
+ consoleError.mockRestore();
205
+ }
206
+ });
207
+
208
+ // Header is the visible half, so a misplaced one blanking an admin screen costs more
209
+ // than the default size it falls back to.
210
+ it('falls back to the default size outside Root in production', function () {
211
+ var previous = process.env.NODE_ENV;
212
+ process.env.NODE_ENV = 'production';
213
+ try {
214
+ var _render10 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Header, {
215
+ title: "Orphan",
216
+ icon: /*#__PURE__*/(0, _jsxRuntime.jsx)("svg", {})
217
+ })),
218
+ container = _render10.container;
219
+ expect(_react.screen.getByRole('heading', {
220
+ level: 2,
221
+ name: 'Orphan'
222
+ })).toBeInTheDocument();
223
+ expect(container.querySelector('.newspack-empty-state__header--small')).not.toBeInTheDocument();
224
+ expect(container.querySelector('.newspack-empty-state__icon svg')).toHaveAttribute('width', '48');
225
+ } finally {
226
+ process.env.NODE_ENV = previous;
227
+ }
228
+ });
229
+ });
230
+ describe('EmptyState.Actions', function () {
231
+ it('renders its children in a centred row', function () {
232
+ var _render11 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
233
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Actions, {
234
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
235
+ type: "button",
236
+ children: "Add Newsletter"
237
+ })
238
+ })
239
+ })),
240
+ container = _render11.container;
241
+ expect(container.querySelector('.newspack-empty-state__actions')).toBeInTheDocument();
242
+ expect(container.querySelector('.newspack-empty-state__actions')).toHaveStyle({
243
+ justifyContent: 'center',
244
+ gap: 'var(--wpds-dimension-gap-sm, 8px)'
245
+ });
246
+ expect(_react.screen.getByRole('button', {
247
+ name: 'Add Newsletter'
248
+ })).toBeInTheDocument();
249
+ });
250
+ it('stacks into a column while keeping the hook class', function () {
251
+ var _render12 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Root, {
252
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_["default"].Actions, {
253
+ orientation: "column",
254
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
255
+ type: "button",
256
+ children: "Set up Audience Management"
257
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("a", {
258
+ href: "https://example.com",
259
+ children: "Learn more"
260
+ })]
261
+ })
262
+ })),
263
+ container = _render12.container;
264
+ var actions = container.querySelector('.newspack-empty-state__actions');
265
+ expect(actions).toBeInTheDocument();
266
+ expect(actions).toHaveStyle({
267
+ flexDirection: 'column'
268
+ });
269
+ // A stack's own default is `stretch`, so without align="center" the buttons
270
+ // would go full-bleed while flexDirection stayed correct.
271
+ expect(actions).toHaveStyle({
272
+ alignItems: 'center'
273
+ });
274
+ });
275
+ it('throws outside Root in development', function () {
276
+ var consoleError = jest.spyOn(console, 'error').mockImplementation(function () {});
277
+ try {
278
+ expect(function () {
279
+ return (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Actions, {
280
+ children: "x"
281
+ }));
282
+ }).toThrow('EmptyState subcomponents must be rendered inside EmptyState.Root.');
283
+ } finally {
284
+ consoleError.mockRestore();
285
+ }
286
+ });
287
+
288
+ // Actions reads nothing from context, so the invariant is a development aid. A
289
+ // stray one must not blank an admin screen in production over a layout hint.
290
+ it('renders outside Root in production', function () {
291
+ var previous = process.env.NODE_ENV;
292
+ process.env.NODE_ENV = 'production';
293
+ try {
294
+ var _render13 = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"].Actions, {
295
+ children: "x"
296
+ })),
297
+ container = _render13.container;
298
+ expect(container.querySelector('.newspack-empty-state__actions')).toBeInTheDocument();
299
+ } finally {
300
+ process.env.NODE_ENV = previous;
301
+ }
302
+ });
303
+ });
@@ -0,0 +1,56 @@
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 _element = require("@wordpress/element");
10
+ var _ui = require("@wordpress/ui");
11
+ var _classnames = _interopRequireDefault(require("classnames"));
12
+ var _grid = _interopRequireDefault(require("../grid"));
13
+ var _context = require("./context");
14
+ require("./style.scss");
15
+ var _jsxRuntime = require("react/jsx-runtime");
16
+ 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; }
17
+ 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; } /**
18
+ * WordPress dependencies.
19
+ */ /**
20
+ * External dependencies.
21
+ */ /**
22
+ * Internal dependencies.
23
+ */ // Positions the stack in columns 2 to 4. `data-` attributes because that is the form
24
+ // grid/style.scss standardised on, after prop filtering was found to drop a bare `end`
25
+ // before it reached the DOM. That file carries the full note.
26
+ var gridColumn = {
27
+ 'data-start': '2',
28
+ 'data-end': '4'
29
+ };
30
+ var Root = function Root(_ref) {
31
+ var _ref$size = _ref.size,
32
+ size = _ref$size === void 0 ? 'default' : _ref$size,
33
+ className = _ref.className,
34
+ children = _ref.children;
35
+ var context = (0, _element.useMemo)(function () {
36
+ return {
37
+ size: size
38
+ };
39
+ }, [size]);
40
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.EmptyStateContext.Provider, {
41
+ value: context,
42
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_grid["default"], {
43
+ className: (0, _classnames["default"])('newspack-empty-state', className),
44
+ columns: 4,
45
+ noMargin: true,
46
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Stack, _objectSpread(_objectSpread({
47
+ className: "newspack-empty-state__stack",
48
+ direction: "column",
49
+ gap: "2xl"
50
+ }, gridColumn), {}, {
51
+ children: children
52
+ }))
53
+ })
54
+ });
55
+ };
56
+ var _default = exports["default"] = Root;
@@ -0,0 +1,51 @@
1
+ @use "~@wordpress/base-styles/colors" as wp-colors;
2
+ @use "~@wordpress/base-styles/mixins" as wp-mixins;
3
+ @use "~@wordpress/base-styles/variables" as wp-vars;
4
+ @use "../../../colors/colors.module" as np-colors;
5
+
6
+ .newspack-empty-state {
7
+ &__stack {
8
+ margin-inline: auto;
9
+ max-width: var(--wpds-dimension-surface-width-lg, 560px);
10
+ }
11
+
12
+ &__header {
13
+ text-align: center;
14
+ text-wrap: balance;
15
+ }
16
+
17
+ &__icon {
18
+ background-color: var(--wp-admin-theme-color-lighter-10, #{np-colors.$primary-000});
19
+ border-radius: 100%;
20
+ display: grid;
21
+ height: wp-vars.$grid-unit-50 * 2;
22
+ place-items: center;
23
+ width: wp-vars.$grid-unit-50 * 2;
24
+
25
+ svg {
26
+ fill: var(--wp-admin-theme-color, #{np-colors.$primary-600});
27
+ }
28
+ }
29
+
30
+ &__title {
31
+ @include wp-mixins.heading-x-large();
32
+ color: var(--wpds-color-foreground-content-neutral, #{wp-colors.$gray-900});
33
+ margin: 0;
34
+ }
35
+
36
+ &__description {
37
+ color: var(--wpds-color-foreground-content-neutral-weak, #{wp-colors.$gray-700});
38
+ margin: 0;
39
+ }
40
+
41
+ &__header--small {
42
+ .newspack-empty-state__icon {
43
+ height: wp-vars.$grid-unit-50;
44
+ width: wp-vars.$grid-unit-50;
45
+ }
46
+
47
+ .newspack-empty-state__title {
48
+ @include wp-mixins.heading-large();
49
+ }
50
+ }
51
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });