newspack-components 4.7.0 → 4.8.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.
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
@@ -2,55 +2,51 @@
2
2
  * CardFeature
3
3
  */
4
4
 
5
- @use "~@wordpress/base-styles/colors" as wp-colors;
5
+ @use "~@wordpress/base-styles/mixins" as wp-mixins;
6
6
  @use "~@wordpress/base-styles/variables" as wp-vars;
7
+ @use "../mixins" as np-mixins;
7
8
 
8
9
  .newspack-card-feature {
9
10
  height: 100%;
10
11
 
11
- .newspack-card--core__header {
12
- height: 100%;
13
- }
14
-
15
- .newspack-card--core__header-content {
16
- gap: 16px;
17
- display: flex;
18
- flex-direction: column;
19
- height: 100%;
12
+ &__actions {
13
+ margin-top: auto;
20
14
 
21
- // Push the action row (buttons + badge) to the bottom.
22
- > :last-child {
23
- margin-top: auto;
15
+ .newspack-card-feature__badge {
16
+ flex-shrink: 1;
17
+ min-width: 0;
24
18
  }
25
19
  }
26
20
 
27
21
  &__content {
28
22
  flex: 1;
29
- min-width: 0; // prevent flex blowout on long words
23
+ min-width: 0;
30
24
  }
31
25
 
32
26
  &__title {
33
- font-size: wp-vars.$font-size-x-large;
34
- line-height: wp-vars.$font-line-height-x-large;
35
- text-align: left;
27
+ @include wp-mixins.heading-x-large();
28
+
29
+ margin: 0;
36
30
  }
37
31
 
38
32
  &__description {
39
- text-align: left;
33
+ @include np-mixins.text-muted;
34
+
35
+ margin: 0;
40
36
  }
41
37
 
42
38
  &__icon {
43
39
  align-items: center;
44
40
  display: flex;
45
- flex: 0 0 40px;
46
- height: 40px;
41
+ flex: 0 0 wp-vars.$grid-unit-50;
42
+ height: wp-vars.$grid-unit-50;
47
43
  justify-content: center;
48
44
 
49
45
  svg {
50
46
  display: block;
51
47
  fill: currentcolor;
52
- height: 24px;
53
- width: 24px;
48
+ height: wp-vars.$grid-unit-30;
49
+ width: wp-vars.$grid-unit-30;
54
50
  }
55
51
 
56
52
  &--radius-small {
@@ -62,14 +58,7 @@
62
58
  }
63
59
  }
64
60
 
65
- // Unmet requirements state: lighter border, muted content.
66
- &.newspack-card-feature--muted {
67
- border-color: wp-colors.$gray-100;
68
- box-shadow: wp-colors.$gray-100 0 0 0 1px;
69
-
70
- .newspack-card-feature__title,
71
- .newspack-card-feature__description {
72
- color: wp-colors.$gray-700;
73
- }
61
+ &.newspack-card-feature--muted &__title {
62
+ @include np-mixins.text-muted;
74
63
  }
75
64
  }
@@ -9,7 +9,7 @@ var _classnames = _interopRequireDefault(require("classnames"));
9
9
  var _element = require("@wordpress/element");
10
10
  var _compose = require("@wordpress/compose");
11
11
  var _components = require("@wordpress/components");
12
- var _badge = _interopRequireDefault(require("../badge"));
12
+ var _ui = require("@wordpress/ui");
13
13
  var _card = _interopRequireDefault(require("../card"));
14
14
  require("./style.scss");
15
15
  var _jsxRuntime = require("react/jsx-runtime");
@@ -36,7 +36,7 @@ var _jsxRuntime = require("react/jsx-runtime");
36
36
  */
37
37
 
38
38
  var _CardForm = function CardForm(_ref) {
39
- var _badge$level;
39
+ var _badge$intent;
40
40
  var title = _ref.title,
41
41
  description = _ref.description,
42
42
  badge = _ref.badge,
@@ -123,9 +123,9 @@ var _CardForm = function CardForm(_ref) {
123
123
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_components.__experimentalHStack, {
124
124
  spacing: 2,
125
125
  expanded: false,
126
- children: [badge && /*#__PURE__*/(0, _jsxRuntime.jsx)(_badge["default"], {
127
- text: badge.text,
128
- level: (_badge$level = badge.level) !== null && _badge$level !== void 0 ? _badge$level : 'success'
126
+ children: [(badge === null || badge === void 0 ? void 0 : badge.label) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Badge, {
127
+ intent: (_badge$intent = badge.intent) !== null && _badge$intent !== void 0 ? _badge$intent : 'stable',
128
+ children: badge.label
129
129
  }), actions]
130
130
  })]
131
131
  })
@@ -10,6 +10,7 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers
10
10
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
11
  var _components = require("@wordpress/components");
12
12
  var _element = require("@wordpress/element");
13
+ var _ui = require("@wordpress/ui");
13
14
  var _ = require("../");
14
15
  require("./style.scss");
15
16
  var _classnames = _interopRequireDefault(require("classnames"));
@@ -384,6 +385,7 @@ var CardSortableList = function CardSortableList(_ref) {
384
385
  onDragEnd: handleDragEnd,
385
386
  appendToOwnerDocument: true,
386
387
  children: function children(_ref2) {
388
+ var _item$badge, _item$badge$intent;
387
389
  var onDraggableStart = _ref2.onDraggableStart,
388
390
  onDraggableEnd = _ref2.onDraggableEnd;
389
391
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_.Card, {
@@ -395,9 +397,9 @@ var CardSortableList = function CardSortableList(_ref) {
395
397
  __experimentalCoreProps: _objectSpread(_objectSpread({
396
398
  header: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
397
399
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("h3", {
398
- children: [item.title, /*#__PURE__*/(0, _jsxRuntime.jsx)(_.Badge, {
399
- level: item.badgeLevel,
400
- text: item.badgeText
400
+ children: [item.title, ((_item$badge = item.badge) === null || _item$badge === void 0 ? void 0 : _item$badge.label) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Badge, {
401
+ intent: (_item$badge$intent = item.badge.intent) !== null && _item$badge$intent !== void 0 ? _item$badge$intent : 'none',
402
+ children: item.badge.label
401
403
  })]
402
404
  }), item.description && /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
403
405
  children: item.description
@@ -0,0 +1,50 @@
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
+ var items = [{
16
+ id: 1,
17
+ title: 'Homepage',
18
+ badge: {
19
+ label: 'Active',
20
+ intent: 'stable'
21
+ }
22
+ }, {
23
+ id: 2,
24
+ title: 'About',
25
+ badge: {
26
+ label: 'Draft',
27
+ intent: 'draft'
28
+ }
29
+ }];
30
+ describe('CardSortableList', function () {
31
+ it('renders a badge for each item that has badge text', function () {
32
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
33
+ items: items
34
+ }));
35
+ expect(_react.screen.getByText('Active')).toBeInTheDocument();
36
+ expect(_react.screen.getByText('Draft')).toBeInTheDocument();
37
+ });
38
+ it('renders no badge for an item without badge text', function () {
39
+ var _render = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_["default"], {
40
+ items: [{
41
+ id: 1,
42
+ title: 'Homepage'
43
+ }]
44
+ })),
45
+ container = _render.container;
46
+ expect(_react.screen.getByText('Homepage')).toBeInTheDocument();
47
+ // An unguarded Badge would still emit an empty span, so assert on element children.
48
+ expect(container.querySelector('h3').children).toHaveLength(0);
49
+ });
50
+ });
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useTitleLevel = exports.TitleLevelContext = void 0;
7
+ var _element = require("@wordpress/element");
8
+ /**
9
+ * WordPress dependencies
10
+ */
11
+
12
+ /**
13
+ * Internal dependencies
14
+ */
15
+
16
+ var TitleLevelContext = exports.TitleLevelContext = (0, _element.createContext)(2);
17
+ var useTitleLevel = exports.useTitleLevel = function useTitleLevel() {
18
+ return (0, _element.useContext)(TitleLevelContext);
19
+ };
@@ -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 _item = _interopRequireDefault(require("./item"));
9
+ var _root = _interopRequireDefault(require("./root"));
10
+ /**
11
+ * CollapsibleGroup
12
+ */
13
+
14
+ /**
15
+ * Internal dependencies
16
+ */
17
+
18
+ // The group is itself renderable, so `Item` hangs off it rather than forming a namespace object like `Drawer`.
19
+ var CollapsibleGroup = Object.assign(_root["default"], {
20
+ Item: _item["default"]
21
+ });
22
+ CollapsibleGroup.displayName = 'CollapsibleGroup';
23
+ _item["default"].displayName = 'CollapsibleGroup.Item';
24
+ var _default = exports["default"] = CollapsibleGroup;
@@ -0,0 +1,215 @@
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 = _interopRequireDefault(require("./index"));
7
+ var _jsxRuntime = require("react/jsx-runtime");
8
+ 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; }
9
+ 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; } /**
10
+ * External dependencies
11
+ */ /**
12
+ * Internal dependencies
13
+ */
14
+ var renderItems = function renderItems(count) {
15
+ var props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
16
+ return (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"], _objectSpread(_objectSpread({}, props), {}, {
17
+ children: Array.from({
18
+ length: count
19
+ }, function (_, i) {
20
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
21
+ title: "Panel ".concat(i),
22
+ children: "content"
23
+ }, i);
24
+ })
25
+ })));
26
+ };
27
+ var dividers = function dividers(container) {
28
+ return container.querySelectorAll('.newspack-divider');
29
+ };
30
+ var items = function items(container) {
31
+ return container.querySelectorAll('.newspack-collapsible-group__item');
32
+ };
33
+ describe('CollapsibleGroup dividers', function () {
34
+ it('renders no divider for a single item', function () {
35
+ var _renderItems = renderItems(1),
36
+ container = _renderItems.container;
37
+ expect(items(container)).toHaveLength(1);
38
+ expect(dividers(container)).toHaveLength(0);
39
+ });
40
+ it('renders a divider between items but not after the last', function () {
41
+ var _renderItems2 = renderItems(3),
42
+ container = _renderItems2.container;
43
+ expect(items(container)).toHaveLength(3);
44
+ expect(dividers(container)).toHaveLength(2);
45
+ expect(container.querySelector('.newspack-collapsible-group').lastElementChild).not.toHaveClass('newspack-divider');
46
+ });
47
+ it('counts only rendered items when placing dividers', function () {
48
+ var _render = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsxs)(_index["default"], {
49
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
50
+ title: "Panel 0",
51
+ children: "content"
52
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
53
+ title: "Panel 1",
54
+ children: "content"
55
+ }), false, 'trailing text']
56
+ })),
57
+ container = _render.container;
58
+ expect(items(container)).toHaveLength(2);
59
+ expect(dividers(container)).toHaveLength(1);
60
+ expect(container.querySelector('.newspack-collapsible-group').lastElementChild).not.toHaveClass('newspack-divider');
61
+ });
62
+ it('renders tertiary dividers', function () {
63
+ var _renderItems3 = renderItems(2),
64
+ container = _renderItems3.container;
65
+ expect(dividers(container)[0]).toHaveClass('newspack-divider--variant-tertiary');
66
+ });
67
+ });
68
+ describe('CollapsibleGroup titleLevel', function () {
69
+ it('renders item titles as h2 by default', function () {
70
+ renderItems(2);
71
+ expect(_react.screen.getAllByRole('heading', {
72
+ level: 2
73
+ })).toHaveLength(2);
74
+ });
75
+ it('renders every item title at the level given', function () {
76
+ renderItems(2, {
77
+ titleLevel: 3
78
+ });
79
+ expect(_react.screen.getAllByRole('heading', {
80
+ level: 3
81
+ })).toHaveLength(2);
82
+ expect(_react.screen.queryByRole('heading', {
83
+ level: 2
84
+ })).not.toBeInTheDocument();
85
+ });
86
+ it('clamps a level above the heading range', function () {
87
+ renderItems(2, {
88
+ titleLevel: 7
89
+ });
90
+ expect(_react.screen.getAllByRole('heading', {
91
+ level: 6
92
+ })).toHaveLength(2);
93
+ });
94
+ it('clamps a level below the heading range', function () {
95
+ renderItems(1, {
96
+ titleLevel: 0
97
+ });
98
+ expect(_react.screen.getByRole('heading', {
99
+ level: 1
100
+ })).toBeInTheDocument();
101
+ });
102
+ it('inherits the level in a nested group', function () {
103
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"], {
104
+ titleLevel: 4,
105
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
106
+ title: "Outer",
107
+ defaultOpen: true,
108
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"], {
109
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
110
+ title: "Inner",
111
+ children: "content"
112
+ })
113
+ })
114
+ })
115
+ }));
116
+ expect(_react.screen.getByRole('heading', {
117
+ level: 4,
118
+ name: 'Inner'
119
+ })).toBeInTheDocument();
120
+ });
121
+ it('inherits the level in a nested group when the title is hidden', function () {
122
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"], {
123
+ titleLevel: 4,
124
+ hideSingleTitle: true,
125
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
126
+ title: "Outer",
127
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"], {
128
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
129
+ title: "Inner",
130
+ children: "content"
131
+ })
132
+ })
133
+ })
134
+ }));
135
+ expect(_react.screen.getByRole('heading', {
136
+ level: 4,
137
+ name: 'Inner'
138
+ })).toBeInTheDocument();
139
+ });
140
+ });
141
+ describe('CollapsibleGroup hideSingleTitle', function () {
142
+ it('keeps the title on a lone item by default', function () {
143
+ renderItems(1);
144
+ expect(_react.screen.getByRole('button', {
145
+ name: 'Panel 0'
146
+ })).toBeInTheDocument();
147
+ });
148
+ it('drops the title and opens a lone item when set', function () {
149
+ renderItems(1, {
150
+ hideSingleTitle: true
151
+ });
152
+ expect(_react.screen.queryByRole('button', {
153
+ name: 'Panel 0'
154
+ })).not.toBeInTheDocument();
155
+ expect(_react.screen.getByText('content')).toBeVisible();
156
+ });
157
+ it('leaves titles alone when there is more than one item', function () {
158
+ renderItems(2, {
159
+ hideSingleTitle: true
160
+ });
161
+ expect(_react.screen.getByRole('button', {
162
+ name: 'Panel 0'
163
+ })).toBeInTheDocument();
164
+ expect(_react.screen.getByRole('button', {
165
+ name: 'Panel 1'
166
+ })).toBeInTheDocument();
167
+ });
168
+ });
169
+ describe('CollapsibleGroup item state', function () {
170
+ it('expands only the item marked defaultOpen', function () {
171
+ (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsxs)(_index["default"], {
172
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
173
+ title: "Open",
174
+ defaultOpen: true,
175
+ children: "open content"
176
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index["default"].Item, {
177
+ title: "Closed",
178
+ children: "closed content"
179
+ })]
180
+ }));
181
+ expect(_react.screen.getByRole('button', {
182
+ name: 'Open'
183
+ })).toHaveAttribute('aria-expanded', 'true');
184
+ expect(_react.screen.getByRole('button', {
185
+ name: 'Closed'
186
+ })).toHaveAttribute('aria-expanded', 'false');
187
+ });
188
+ it('leaves a collapsed panel reachable by find-in-page', function () {
189
+ var _renderItems4 = renderItems(1),
190
+ container = _renderItems4.container;
191
+ expect(container.querySelector('.newspack-collapsible-group__panel')).toHaveAttribute('hidden', 'until-found');
192
+ expect(_react.screen.getByText('content')).toBeInTheDocument();
193
+ });
194
+ it('opens an item when its trigger is clicked', function () {
195
+ var _renderItems5 = renderItems(1),
196
+ container = _renderItems5.container;
197
+ var trigger = _react.screen.getByRole('button', {
198
+ name: 'Panel 0'
199
+ });
200
+ _react.fireEvent.click(trigger);
201
+ expect(trigger).toHaveAttribute('aria-expanded', 'true');
202
+ expect(container.querySelector('.newspack-collapsible-group__panel')).not.toHaveAttribute('hidden');
203
+ });
204
+ it('closes an open item when its trigger is clicked', function () {
205
+ var _renderItems6 = renderItems(1),
206
+ container = _renderItems6.container;
207
+ var trigger = _react.screen.getByRole('button', {
208
+ name: 'Panel 0'
209
+ });
210
+ _react.fireEvent.click(trigger);
211
+ _react.fireEvent.click(trigger);
212
+ expect(trigger).toHaveAttribute('aria-expanded', 'false');
213
+ expect(container.querySelector('.newspack-collapsible-group__panel')).toHaveAttribute('hidden', 'until-found');
214
+ });
215
+ });
@@ -0,0 +1,61 @@
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 Item = function Item(_ref) {
26
+ var children = _ref.children,
27
+ className = _ref.className,
28
+ _ref$defaultOpen = _ref.defaultOpen,
29
+ defaultOpen = _ref$defaultOpen === void 0 ? false : _ref$defaultOpen,
30
+ title = _ref.title;
31
+ var titleLevel = (0, _context.useTitleLevel)();
32
+ if (!title) {
33
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
34
+ className: (0, _classnames["default"])('newspack-collapsible-group__item', className),
35
+ children: children
36
+ });
37
+ }
38
+ var Heading = "h".concat(titleLevel);
39
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ui.Collapsible.Root, {
40
+ className: (0, _classnames["default"])('newspack-collapsible-group__item', className),
41
+ defaultOpen: defaultOpen,
42
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Heading, {
43
+ className: "newspack-collapsible-group__heading",
44
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_ui.Collapsible.Trigger, {
45
+ className: "newspack-collapsible-group__trigger",
46
+ children: [title, /*#__PURE__*/(0, _jsxRuntime.jsx)(_icons.Icon, {
47
+ icon: _icons.chevronDown,
48
+ size: 24
49
+ })]
50
+ })
51
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Collapsible.Panel, {
52
+ className: "newspack-collapsible-group__panel",
53
+ hiddenUntilFound: true,
54
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
55
+ className: "newspack-collapsible-group__panel-inner",
56
+ children: children
57
+ })
58
+ })]
59
+ });
60
+ };
61
+ var _default = exports["default"] = Item;
@@ -0,0 +1,62 @@
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 _element = require("@wordpress/element");
9
+ var _ui = require("@wordpress/ui");
10
+ var _classnames = _interopRequireDefault(require("classnames"));
11
+ var _divider = _interopRequireDefault(require("../divider"));
12
+ var _context = require("./context");
13
+ require("./style.scss");
14
+ var _jsxRuntime = require("react/jsx-runtime");
15
+ /**
16
+ * WordPress dependencies
17
+ */
18
+
19
+ /**
20
+ * External dependencies
21
+ */
22
+
23
+ /**
24
+ * Internal dependencies
25
+ */
26
+
27
+ var clampTitleLevel = function clampTitleLevel(level) {
28
+ return Number.isFinite(level) ? Math.min(6, Math.max(1, Math.round(level))) : undefined;
29
+ };
30
+ var Root = function Root(_ref) {
31
+ var _clampTitleLevel;
32
+ var children = _ref.children,
33
+ className = _ref.className,
34
+ _ref$gap = _ref.gap,
35
+ gap = _ref$gap === void 0 ? 'xl' : _ref$gap,
36
+ _ref$hideSingleTitle = _ref.hideSingleTitle,
37
+ hideSingleTitle = _ref$hideSingleTitle === void 0 ? false : _ref$hideSingleTitle,
38
+ titleLevel = _ref.titleLevel;
39
+ var inheritedTitleLevel = (0, _context.useTitleLevel)();
40
+ var items = _element.Children.toArray(children).filter(_element.isValidElement);
41
+ var hideTitle = hideSingleTitle && items.length === 1;
42
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.TitleLevelContext.Provider, {
43
+ value: (_clampTitleLevel = clampTitleLevel(titleLevel)) !== null && _clampTitleLevel !== void 0 ? _clampTitleLevel : inheritedTitleLevel,
44
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ui.Stack, {
45
+ className: (0, _classnames["default"])('newspack-collapsible-group', className),
46
+ direction: "column",
47
+ gap: gap,
48
+ children: items.map(function (item, index) {
49
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_element.Fragment, {
50
+ children: [hideTitle ? (0, _element.cloneElement)(item, {
51
+ title: undefined
52
+ }) : item, index < items.length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_divider["default"], {
53
+ variant: "tertiary",
54
+ marginBottom: 0,
55
+ marginTop: 0
56
+ })]
57
+ }, item.key);
58
+ })
59
+ })
60
+ });
61
+ };
62
+ var _default = exports["default"] = Root;
@@ -0,0 +1,47 @@
1
+ @use "../mixins" as mixins;
2
+ @use "~@wordpress/base-styles/mixins" as wp-mixins;
3
+ @use "~@wordpress/base-styles/variables" as wp-vars;
4
+
5
+ .newspack-collapsible-group {
6
+ &__heading {
7
+ margin: 0;
8
+ }
9
+
10
+ &__trigger {
11
+ @include wp-mixins.heading-large();
12
+ align-items: center;
13
+ background: none;
14
+ border: 0;
15
+ color: inherit;
16
+ cursor: pointer;
17
+ display: flex;
18
+ gap: wp-vars.$grid-unit-10;
19
+ justify-content: space-between;
20
+ padding: 0;
21
+ text-align: left;
22
+ width: 100%;
23
+
24
+ &:focus-visible {
25
+ @include mixins.wpds-focus-ring;
26
+ outline-offset: wp-vars.$grid-unit-05;
27
+ }
28
+
29
+ svg {
30
+ flex-shrink: 0;
31
+ }
32
+
33
+ &[aria-expanded="true"] svg {
34
+ transform: rotate(180deg);
35
+ }
36
+
37
+ @media (prefers-reduced-motion: no-preference) {
38
+ svg {
39
+ transition: transform 0.1s ease-out;
40
+ }
41
+ }
42
+ }
43
+
44
+ &__panel-inner {
45
+ padding-top: wp-vars.$grid-unit-30;
46
+ }
47
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });