newspack-components 2.0.1 → 2.1.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/copy-styles.js +1 -1
  2. package/dist/cjs/action-card/index.js +32 -22
  3. package/dist/cjs/action-card/style.scss +52 -27
  4. package/dist/cjs/autocomplete-tokenfield/style.scss +4 -4
  5. package/dist/cjs/autocomplete-with-suggestions/index.js +3 -2
  6. package/dist/cjs/autocomplete-with-suggestions/style.scss +19 -20
  7. package/dist/cjs/button/index.js +2 -13
  8. package/dist/cjs/button/style.scss +3 -344
  9. package/dist/cjs/button-card/index.js +11 -6
  10. package/dist/cjs/button-card/style.scss +69 -35
  11. package/dist/cjs/card/index.js +3 -1
  12. package/dist/cjs/card/style.scss +34 -61
  13. package/dist/cjs/category-autocomplete/index.js +52 -13
  14. package/dist/cjs/category-autocomplete/style.scss +19 -15
  15. package/dist/cjs/color-picker/index.js +17 -35
  16. package/dist/cjs/color-picker/style.scss +20 -160
  17. package/dist/cjs/custom-select-control/style.scss +12 -42
  18. package/dist/cjs/footer/index.js +21 -7
  19. package/dist/cjs/footer/style.scss +9 -10
  20. package/dist/cjs/form-token-field/index.js +2 -2
  21. package/dist/cjs/form-token-field/style.scss +8 -103
  22. package/dist/cjs/global-notices/index.js +2 -1
  23. package/dist/cjs/grid/index.js +1 -1
  24. package/dist/cjs/grid/style.scss +29 -1
  25. package/dist/cjs/handoff/index.js +7 -7
  26. package/dist/cjs/image-upload/index.js +1 -1
  27. package/dist/cjs/image-upload/style.scss +10 -11
  28. package/dist/cjs/index.js +7 -53
  29. package/dist/cjs/modal/index.js +0 -3
  30. package/dist/cjs/modal/style.scss +19 -131
  31. package/dist/cjs/newspack-icon/index.js +4 -2
  32. package/dist/cjs/newspack-icon/style.scss +15 -0
  33. package/dist/cjs/notice/index.js +8 -9
  34. package/dist/cjs/notice/style.scss +38 -10
  35. package/dist/cjs/plugin-installer/index.js +4 -2
  36. package/dist/cjs/plugin-settings/SettingsSection.js +76 -45
  37. package/dist/cjs/plugin-settings/index.js +49 -34
  38. package/dist/cjs/plugin-settings/style.scss +7 -0
  39. package/dist/cjs/plugin-toggle/index.js +22 -1
  40. package/dist/cjs/popover/style.scss +2 -2
  41. package/dist/cjs/radio-control/style.scss +1 -2
  42. package/dist/cjs/section-header/index.js +18 -5
  43. package/dist/cjs/section-header/style.scss +26 -1
  44. package/dist/cjs/select-control/ButtonGroupControl.js +8 -8
  45. package/dist/cjs/select-control/GroupedSelectControl.js +33 -30
  46. package/dist/cjs/select-control/index.js +1 -2
  47. package/dist/cjs/select-control/style.scss +46 -87
  48. package/dist/cjs/settings/MinMaxSetting.js +4 -2
  49. package/dist/cjs/settings/SettingsCard.js +6 -1
  50. package/dist/cjs/settings/SettingsSection.js +4 -4
  51. package/dist/cjs/settings/style.scss +32 -4
  52. package/dist/cjs/style-card/index.js +10 -6
  53. package/dist/cjs/style-card/style.scss +12 -8
  54. package/dist/cjs/style.scss +44 -0
  55. package/dist/cjs/tabbed-navigation/index.js +13 -20
  56. package/dist/cjs/tabbed-navigation/style.scss +56 -34
  57. package/dist/cjs/text-control/index.js +0 -3
  58. package/dist/cjs/text-control/style.scss +0 -126
  59. package/dist/cjs/waiting/index.js +9 -25
  60. package/dist/cjs/waiting/style.scss +9 -20
  61. package/dist/cjs/web-preview/index.js +18 -30
  62. package/dist/cjs/web-preview/style.scss +33 -26
  63. package/dist/cjs/with-wizard/index.js +4 -2
  64. package/dist/cjs/with-wizard/style.scss +77 -89
  65. package/dist/cjs/with-wizard-screen/index.js +17 -21
  66. package/dist/cjs/with-wizard-screen/style.scss +74 -121
  67. package/dist/cjs/wizard/components/WizardError.js +86 -0
  68. package/dist/cjs/wizard/index.js +145 -0
  69. package/dist/cjs/wizard/store/index.js +178 -0
  70. package/dist/cjs/wizard/store/utils.js +31 -0
  71. package/dist/esm/action-card/index.js +33 -23
  72. package/dist/esm/action-card/style.scss +52 -27
  73. package/dist/esm/autocomplete-tokenfield/style.scss +4 -4
  74. package/dist/esm/autocomplete-with-suggestions/index.js +3 -2
  75. package/dist/esm/autocomplete-with-suggestions/style.scss +19 -20
  76. package/dist/esm/button/index.js +2 -12
  77. package/dist/esm/button/style.scss +3 -344
  78. package/dist/esm/button-card/index.js +10 -6
  79. package/dist/esm/button-card/style.scss +69 -35
  80. package/dist/esm/card/index.js +3 -1
  81. package/dist/esm/card/style.scss +34 -61
  82. package/dist/esm/category-autocomplete/index.js +54 -14
  83. package/dist/esm/category-autocomplete/style.scss +19 -15
  84. package/dist/esm/color-picker/index.js +15 -34
  85. package/dist/esm/color-picker/style.scss +20 -160
  86. package/dist/esm/custom-select-control/style.scss +12 -42
  87. package/dist/esm/footer/index.js +21 -7
  88. package/dist/esm/footer/style.scss +9 -10
  89. package/dist/esm/form-token-field/index.js +2 -2
  90. package/dist/esm/form-token-field/style.scss +8 -103
  91. package/dist/esm/global-notices/index.js +2 -1
  92. package/dist/esm/grid/index.js +1 -1
  93. package/dist/esm/grid/style.scss +29 -1
  94. package/dist/esm/handoff/index.js +7 -7
  95. package/dist/esm/image-upload/index.js +1 -1
  96. package/dist/esm/image-upload/style.scss +10 -11
  97. package/dist/esm/index.js +3 -8
  98. package/dist/esm/modal/index.js +0 -3
  99. package/dist/esm/modal/style.scss +19 -131
  100. package/dist/esm/newspack-icon/index.js +4 -2
  101. package/dist/esm/newspack-icon/style.scss +15 -0
  102. package/dist/esm/notice/index.js +8 -3
  103. package/dist/esm/notice/style.scss +38 -10
  104. package/dist/esm/plugin-installer/index.js +5 -2
  105. package/dist/esm/plugin-settings/SettingsSection.js +74 -46
  106. package/dist/esm/plugin-settings/index.js +48 -34
  107. package/dist/esm/plugin-settings/style.scss +7 -0
  108. package/dist/esm/plugin-toggle/index.js +23 -1
  109. package/dist/esm/popover/style.scss +2 -2
  110. package/dist/esm/radio-control/style.scss +1 -2
  111. package/dist/esm/section-header/index.js +17 -5
  112. package/dist/esm/section-header/style.scss +26 -1
  113. package/dist/esm/select-control/ButtonGroupControl.js +8 -8
  114. package/dist/esm/select-control/GroupedSelectControl.js +33 -30
  115. package/dist/esm/select-control/index.js +1 -2
  116. package/dist/esm/select-control/style.scss +46 -87
  117. package/dist/esm/settings/MinMaxSetting.js +3 -2
  118. package/dist/esm/settings/SettingsCard.js +6 -1
  119. package/dist/esm/settings/SettingsSection.js +5 -5
  120. package/dist/esm/settings/style.scss +32 -4
  121. package/dist/esm/style-card/index.js +11 -8
  122. package/dist/esm/style-card/style.scss +12 -8
  123. package/dist/esm/style.scss +44 -0
  124. package/dist/esm/tabbed-navigation/index.js +14 -22
  125. package/dist/esm/tabbed-navigation/style.scss +56 -34
  126. package/dist/esm/text-control/index.js +0 -3
  127. package/dist/esm/text-control/style.scss +0 -126
  128. package/dist/esm/waiting/index.js +9 -22
  129. package/dist/esm/waiting/style.scss +9 -20
  130. package/dist/esm/web-preview/index.js +12 -25
  131. package/dist/esm/web-preview/style.scss +33 -26
  132. package/dist/esm/with-wizard/index.js +4 -2
  133. package/dist/esm/with-wizard/style.scss +77 -89
  134. package/dist/esm/with-wizard-screen/index.js +18 -22
  135. package/dist/esm/with-wizard-screen/style.scss +74 -121
  136. package/dist/esm/wizard/components/WizardError.js +78 -0
  137. package/dist/esm/wizard/index.js +128 -0
  138. package/dist/esm/wizard/store/index.js +161 -0
  139. package/dist/esm/wizard/store/utils.js +17 -0
  140. package/package.json +2 -1
  141. package/shared/scss/_colors.scss +15 -0
  142. package/src/action-card/index.js +31 -19
  143. package/src/action-card/style.scss +52 -27
  144. package/src/autocomplete-tokenfield/style.scss +4 -4
  145. package/src/autocomplete-with-suggestions/index.js +4 -2
  146. package/src/autocomplete-with-suggestions/style.scss +19 -20
  147. package/src/button/index.js +2 -9
  148. package/src/button/style.scss +3 -344
  149. package/src/button-card/index.js +19 -5
  150. package/src/button-card/style.scss +69 -35
  151. package/src/card/index.js +4 -0
  152. package/src/card/style.scss +34 -61
  153. package/src/category-autocomplete/index.js +51 -18
  154. package/src/category-autocomplete/style.scss +19 -15
  155. package/src/color-picker/index.js +16 -22
  156. package/src/color-picker/style.scss +20 -160
  157. package/src/custom-select-control/style.scss +12 -42
  158. package/src/footer/index.js +19 -8
  159. package/src/footer/style.scss +9 -10
  160. package/src/form-token-field/index.js +1 -1
  161. package/src/form-token-field/style.scss +8 -103
  162. package/src/global-notices/index.js +1 -1
  163. package/src/grid/index.js +1 -1
  164. package/src/grid/style.scss +29 -1
  165. package/src/handoff/index.js +7 -7
  166. package/src/image-upload/style.scss +10 -11
  167. package/src/index.js +3 -7
  168. package/src/modal/index.js +2 -5
  169. package/src/modal/style.scss +19 -131
  170. package/src/newspack-icon/index.js +7 -2
  171. package/src/newspack-icon/style.scss +15 -0
  172. package/src/notice/index.js +7 -1
  173. package/src/notice/style.scss +38 -10
  174. package/src/plugin-installer/index.js +4 -2
  175. package/src/plugin-settings/SettingsSection.js +65 -27
  176. package/src/plugin-settings/index.js +45 -18
  177. package/src/plugin-settings/style.scss +7 -0
  178. package/src/plugin-toggle/index.js +35 -9
  179. package/src/popover/style.scss +2 -2
  180. package/src/radio-control/style.scss +1 -2
  181. package/src/section-header/index.js +25 -6
  182. package/src/section-header/style.scss +26 -1
  183. package/src/select-control/ButtonGroupControl.js +13 -6
  184. package/src/select-control/GroupedSelectControl.js +26 -24
  185. package/src/select-control/index.js +1 -2
  186. package/src/select-control/style.scss +46 -87
  187. package/src/settings/MinMaxSetting.js +2 -1
  188. package/src/settings/SettingsCard.js +9 -7
  189. package/src/settings/SettingsSection.js +4 -4
  190. package/src/settings/style.scss +32 -4
  191. package/src/style-card/index.js +14 -16
  192. package/src/style-card/style.scss +12 -8
  193. package/src/style.scss +44 -0
  194. package/src/tabbed-navigation/index.js +12 -24
  195. package/src/tabbed-navigation/style.scss +56 -34
  196. package/src/text-control/index.js +1 -2
  197. package/src/text-control/style.scss +0 -126
  198. package/src/waiting/index.js +7 -18
  199. package/src/waiting/style.scss +9 -20
  200. package/src/web-preview/index.js +12 -33
  201. package/src/web-preview/style.scss +33 -26
  202. package/src/with-wizard/index.js +7 -5
  203. package/src/with-wizard/style.scss +77 -89
  204. package/src/with-wizard-screen/index.js +14 -17
  205. package/src/with-wizard-screen/style.scss +74 -121
  206. package/src/wizard/components/WizardError.js +57 -0
  207. package/src/wizard/index.js +133 -0
  208. package/src/wizard/store/index.js +126 -0
  209. package/src/wizard/store/utils.js +16 -0
  210. package/dist/cjs/button-group/index.js +0 -57
  211. package/dist/cjs/button-group/style.scss +0 -68
  212. package/dist/cjs/checkbox-control/index.js +0 -63
  213. package/dist/cjs/checkbox-control/style.scss +0 -78
  214. package/dist/cjs/preview-box/index.js +0 -36
  215. package/dist/cjs/preview-box/style.scss +0 -18
  216. package/dist/cjs/textarea-control/index.js +0 -54
  217. package/dist/cjs/textarea-control/style.scss +0 -76
  218. package/dist/cjs/toggle-control/index.js +0 -58
  219. package/dist/cjs/toggle-control/style.scss +0 -74
  220. package/dist/cjs/toggle-group/index.js +0 -71
  221. package/dist/cjs/toggle-group/style.scss +0 -28
  222. package/dist/cjs/wizard-pagination/index.js +0 -71
  223. package/dist/cjs/wizard-pagination/style.scss +0 -74
  224. package/dist/esm/button-group/index.js +0 -43
  225. package/dist/esm/button-group/style.scss +0 -68
  226. package/dist/esm/checkbox-control/index.js +0 -49
  227. package/dist/esm/checkbox-control/style.scss +0 -78
  228. package/dist/esm/preview-box/index.js +0 -30
  229. package/dist/esm/preview-box/style.scss +0 -18
  230. package/dist/esm/textarea-control/index.js +0 -40
  231. package/dist/esm/textarea-control/style.scss +0 -76
  232. package/dist/esm/toggle-control/index.js +0 -44
  233. package/dist/esm/toggle-control/style.scss +0 -74
  234. package/dist/esm/toggle-group/index.js +0 -58
  235. package/dist/esm/toggle-group/style.scss +0 -28
  236. package/dist/esm/wizard-pagination/index.js +0 -57
  237. package/dist/esm/wizard-pagination/style.scss +0 -74
  238. package/src/button-group/index.js +0 -35
  239. package/src/button-group/style.scss +0 -68
  240. package/src/checkbox-control/index.js +0 -38
  241. package/src/checkbox-control/style.scss +0 -78
  242. package/src/preview-box/index.js +0 -18
  243. package/src/preview-box/style.scss +0 -18
  244. package/src/textarea-control/index.js +0 -32
  245. package/src/textarea-control/style.scss +0 -76
  246. package/src/toggle-control/index.js +0 -38
  247. package/src/toggle-control/style.scss +0 -74
  248. package/src/toggle-group/index.js +0 -43
  249. package/src/toggle-group/style.scss +0 -28
  250. package/src/wizard-pagination/index.js +0 -59
  251. package/src/wizard-pagination/style.scss +0 -74
@@ -6,7 +6,8 @@
6
6
  * WordPress dependencies.
7
7
  */
8
8
  import { Component, RawHTML } from '@wordpress/element';
9
- import { Icon, check, help, info } from '@wordpress/icons';
9
+ import { Icon, bug, check, help, info } from '@wordpress/icons';
10
+ import { __ } from '@wordpress/i18n';
10
11
 
11
12
  /**
12
13
  * Internal dependencies.
@@ -25,6 +26,7 @@ class Notice extends Component {
25
26
  render() {
26
27
  const {
27
28
  className,
29
+ debugMode,
28
30
  isError,
29
31
  isHelp,
30
32
  isSuccess,
@@ -37,6 +39,7 @@ class Notice extends Component {
37
39
  const classes = classnames(
38
40
  'newspack-notice',
39
41
  className,
42
+ debugMode && 'newspack-notice__is-debug',
40
43
  isError && 'newspack-notice__is-error',
41
44
  isHelp && 'newspack-notice__is-help',
42
45
  isSuccess && 'newspack-notice__is-success',
@@ -47,6 +50,8 @@ class Notice extends Component {
47
50
  noticeIcon = help;
48
51
  } else if ( isSuccess ) {
49
52
  noticeIcon = check;
53
+ } else if ( debugMode ) {
54
+ noticeIcon = bug;
50
55
  } else {
51
56
  noticeIcon = info;
52
57
  }
@@ -55,6 +60,7 @@ class Notice extends Component {
55
60
  { <Icon icon={ noticeIcon } /> }
56
61
  <div className="newspack-notice__content">
57
62
  { rawHTML ? <RawHTML>{ noticeText }</RawHTML> : noticeText }
63
+ { debugMode && __( 'Debug Mode', 'newspack' ) }
58
64
  { children || null }
59
65
  </div>
60
66
  </div>
@@ -6,14 +6,11 @@
6
6
  @import '../../../shared/scss/colors';
7
7
 
8
8
  .newspack-notice {
9
- align-items: flex-start;
9
+ align-items: center;
10
10
  background: $gray-100;
11
- border-radius: 3px;
12
11
  color: $gray-900;
13
12
  display: flex;
14
- font-size: 14px;
15
13
  justify-content: flex-start;
16
- line-height: 24px;
17
14
  margin: 32px 0;
18
15
  padding: 6px 8px;
19
16
 
@@ -24,8 +21,25 @@
24
21
  margin-right: 4px;
25
22
  }
26
23
 
24
+ &__is-debug {
25
+ background: $primary-700;
26
+ border-radius: 2px;
27
+ bottom: 16px;
28
+ box-shadow: 0 0 8px 4px rgba( black, 0.08 );
29
+ color: white;
30
+ font-weight: bold;
31
+ margin: 0 16px;
32
+ position: fixed;
33
+ text-transform: uppercase;
34
+ z-index: 9997;
35
+
36
+ > svg {
37
+ fill: white;
38
+ }
39
+ }
40
+
27
41
  &__is-error {
28
- background: lighten( $alert-red, 54% );
42
+ background: lighten( $alert-red, 51% );
29
43
 
30
44
  > svg {
31
45
  fill: $alert-red;
@@ -34,7 +48,7 @@
34
48
  }
35
49
 
36
50
  &__is-help {
37
- background: $primary-000;
51
+ background: $primary-050;
38
52
 
39
53
  > svg {
40
54
  fill: $primary-500;
@@ -42,7 +56,7 @@
42
56
  }
43
57
 
44
58
  &__is-success {
45
- background: lighten( $alert-green, 47% );
59
+ background: lighten( $alert-green, 42% );
46
60
 
47
61
  > svg {
48
62
  fill: $alert-green;
@@ -50,7 +64,7 @@
50
64
  }
51
65
 
52
66
  &__is-warning {
53
- background: lighten( $alert-yellow, 36% );
67
+ background: lighten( $alert-yellow, 30% );
54
68
 
55
69
  > svg {
56
70
  fill: $alert-yellow;
@@ -58,9 +72,23 @@
58
72
  }
59
73
  }
60
74
 
61
- &__content {
75
+ & &__content {
62
76
  > div > * {
63
- margin: 0;
77
+ margin: 0 !important;
78
+ }
79
+
80
+ a {
81
+ color: inherit;
82
+
83
+ &:active,
84
+ &:focus,
85
+ &:hover {
86
+ color: inherit;
87
+ }
88
+
89
+ &:focus {
90
+ box-shadow: 0 0 0 var( --wp-admin-border-width-focus ) currentColor;
91
+ }
64
92
  }
65
93
  }
66
94
 
@@ -99,6 +99,7 @@ class PluginInstaller extends Component {
99
99
  return apiFetch( params )
100
100
  .then( response => {
101
101
  const { pluginInfo } = this.state;
102
+ this.props.onInstalled( slug );
102
103
  this.updatePluginInfo( {
103
104
  ...pluginInfo,
104
105
  [ slug ]: { ...response, installationStatus: PLUGIN_STATE_ACTIVE },
@@ -177,7 +178,7 @@ class PluginInstaller extends Component {
177
178
  } );
178
179
 
179
180
  return (
180
- <div>
181
+ <>
181
182
  { ( ! pluginInfo || ! Object.keys( pluginInfo ).length ) && (
182
183
  <div className="newspack-plugin-installer_is-waiting">
183
184
  <Waiting isLeft />
@@ -247,13 +248,14 @@ class PluginInstaller extends Component {
247
248
  </Button>
248
249
  </div>
249
250
  ) }
250
- </div>
251
+ </>
251
252
  );
252
253
  }
253
254
  }
254
255
 
255
256
  PluginInstaller.defaultProps = {
256
257
  onStatus: () => {},
258
+ onInstalled: () => {},
257
259
  };
258
260
 
259
261
  export default PluginInstaller;
@@ -6,15 +6,21 @@
6
6
  * WordPress dependencies
7
7
  */
8
8
  import { Fragment } from '@wordpress/element';
9
+ import { applyFilters } from '@wordpress/hooks';
9
10
  import { __ } from '@wordpress/i18n';
11
+ import { CheckboxControl } from '@wordpress/components';
10
12
 
11
13
  /**
12
14
  * Internal dependencies
13
15
  */
14
- import { ActionCard, Grid, Button, TextControl, CheckboxControl, SelectControl } from '../';
16
+ import { ActionCard, Button, Grid, Notice, SelectControl, TextControl } from '../';
17
+ import './style.scss';
15
18
 
19
+ const isSelectControl = setting => {
20
+ return Array.isArray( setting.options ) && setting.options.length;
21
+ };
16
22
  const getControlComponent = setting => {
17
- if ( Array.isArray( setting.options ) && setting.options.length ) {
23
+ if ( isSelectControl( setting ) ) {
18
24
  return SelectControl;
19
25
  }
20
26
  switch ( setting.type ) {
@@ -35,20 +41,28 @@ const getControlType = setting => {
35
41
  case 'string':
36
42
  case 'text':
37
43
  return 'text';
44
+ case 'password':
45
+ return 'password';
46
+ case 'boolean':
47
+ case 'checkbox':
48
+ return 'checkbox';
38
49
  default:
39
50
  return null;
40
51
  }
41
52
  };
42
53
 
43
- const SettingsSection = ( {
44
- active,
45
- title,
46
- description,
47
- fields,
48
- disabled,
49
- onChange,
50
- onUpdate,
51
- } ) => {
54
+ const SettingsSection = props => {
55
+ const {
56
+ error,
57
+ sectionKey,
58
+ active,
59
+ title,
60
+ description,
61
+ fields,
62
+ disabled,
63
+ onChange,
64
+ onUpdate,
65
+ } = props;
52
66
  const getControlProps = setting => ( {
53
67
  disabled,
54
68
  name: `${ setting.section }_${ setting.key }`,
@@ -58,14 +72,28 @@ const SettingsSection = ( {
58
72
  options:
59
73
  setting.options?.map( option => ( {
60
74
  value: option.value,
61
- label: option.name,
75
+ label: option.name || option.label,
62
76
  } ) ) || null,
63
77
  value: setting.value,
78
+ multiple: isSelectControl( setting ) && setting.multiple ? true : null,
64
79
  checked: setting.type === 'boolean' ? !! setting.value : null,
65
80
  onChange: value => {
66
81
  onChange( setting.key, value );
67
82
  },
68
83
  } );
84
+ const createFilter = ( name, defaultComponent = null ) => {
85
+ return applyFilters(
86
+ `newspack.settingSection.${ sectionKey }.${ name }`,
87
+ defaultComponent,
88
+ props
89
+ );
90
+ };
91
+ let columns = 2;
92
+ if ( fields.length % 3 === 0 ) {
93
+ columns = 3;
94
+ } else if ( fields.length === 1 ) {
95
+ columns = 1;
96
+ }
69
97
  return (
70
98
  <ActionCard
71
99
  isMedium
@@ -73,28 +101,38 @@ const SettingsSection = ( {
73
101
  title={ title }
74
102
  description={ description }
75
103
  toggleChecked={ active }
76
- hasGreyHeader={ active !== null }
77
- toggleOnChange={ value => onUpdate( { active: value } ) }
104
+ hasGreyHeader={ active || null === active }
105
+ toggleOnChange={ active !== null ? value => onUpdate( { active: value } ) : null }
106
+ actionContent={
107
+ ( active || null === active ) &&
108
+ createFilter(
109
+ 'buttons',
110
+ <Button
111
+ variant="primary"
112
+ disabled={ disabled }
113
+ onClick={ () => {
114
+ onUpdate();
115
+ } }
116
+ >
117
+ { __( 'Save Settings', 'newspack' ) }
118
+ </Button>
119
+ )
120
+ }
78
121
  >
79
122
  { ( active || active === null ) && (
80
123
  <Fragment>
81
- <Grid columns={ fields.length % 3 === 0 ? 3 : 2 } gutter={ 32 }>
124
+ { error?.message && <Notice noticeText={ error.message } isError /> }
125
+ { createFilter( 'beforeControls' ) }
126
+ <Grid columns={ columns } gutter={ 32 }>
82
127
  { fields.map( setting => {
83
128
  const Control = getControlComponent( setting ); // eslint-disable-line @wordpress/no-unused-vars-before-return, no-unused-vars
84
- return <Control key={ setting.key } { ...getControlProps( setting ) } />;
129
+ return applyFilters(
130
+ `newspack.settingsSection.${ sectionKey }.control`,
131
+ <Control key={ setting.key } { ...getControlProps( setting ) } />,
132
+ { sectionKey, setting, onChange }
133
+ );
85
134
  } ) }
86
135
  </Grid>
87
- <div className="newspack-buttons-card" style={ { margin: '32px 0 0' } }>
88
- <Button
89
- isPrimary
90
- disabled={ disabled }
91
- onClick={ () => {
92
- onUpdate();
93
- } }
94
- >
95
- { __( 'Save settings', 'newspack' ) }
96
- </Button>
97
- </div>
98
136
  </Fragment>
99
137
  ) }
100
138
  </ActionCard>
@@ -1,3 +1,8 @@
1
+ /**
2
+ * External dependencies
3
+ */
4
+ import classnames from 'classnames';
5
+
1
6
  /**
2
7
  * WordPress dependencies.
3
8
  */
@@ -22,11 +27,18 @@ class PluginSettings extends Component {
22
27
  }
23
28
 
24
29
  fetchSettings = () => {
25
- const { pluginSlug } = this.props;
30
+ const { afterFetch, pluginSlug, isWizard } = this.props;
26
31
  this.setState( { inFlight: true } );
27
- apiFetch( { path: `/${ pluginSlug }/v1/settings` } )
32
+ apiFetch( {
33
+ path: isWizard
34
+ ? `/newspack/v1/wizard/${ pluginSlug }/settings`
35
+ : `/${ pluginSlug }/v1/settings`,
36
+ } )
28
37
  .then( settings => {
29
38
  this.setState( { settings, error: null } );
39
+ if ( 'function' === typeof afterFetch ) {
40
+ afterFetch( settings );
41
+ }
30
42
  } )
31
43
  .catch( error => {
32
44
  this.setState( { error } );
@@ -65,10 +77,12 @@ class PluginSettings extends Component {
65
77
  };
66
78
 
67
79
  handleSectionUpdate = sectionKey => data => {
68
- const { pluginSlug } = this.props;
80
+ const { afterUpdate, pluginSlug, isWizard } = this.props;
69
81
  this.setState( { inFlight: true } );
70
82
  apiFetch( {
71
- path: `/${ pluginSlug }/v1/settings`,
83
+ path: isWizard
84
+ ? `/newspack/v1/wizard/${ pluginSlug }/settings`
85
+ : `/${ pluginSlug }/v1/settings`,
72
86
  method: 'POST',
73
87
  data: {
74
88
  section: sectionKey,
@@ -77,6 +91,10 @@ class PluginSettings extends Component {
77
91
  } )
78
92
  .then( settings => {
79
93
  this.setState( { settings, error: null } );
94
+
95
+ if ( 'function' === typeof afterUpdate ) {
96
+ afterUpdate( settings );
97
+ }
80
98
  } )
81
99
  .catch( error => {
82
100
  this.setState( { error } );
@@ -149,24 +167,33 @@ class PluginSettings extends Component {
149
167
  * Render.
150
168
  */
151
169
  render() {
152
- const { title, description } = this.props;
170
+ const { title, description, hasGreyHeader, children } = this.props;
153
171
  const { settings, inFlight, error } = this.state;
154
172
  return (
155
173
  <Fragment>
156
- <SectionHeader title={ title } description={ description } />
174
+ { title && <SectionHeader title={ title } description={ description } /> }
157
175
  { error && <Notice isError noticeText={ error.message } /> }
158
- { Object.keys( settings ).map( sectionKey => (
159
- <SettingsSection
160
- key={ sectionKey }
161
- disabled={ inFlight }
162
- title={ this.getSectionTitle( sectionKey ) }
163
- description={ this.getSectionDescription( sectionKey ) }
164
- active={ this.isSectionActive( sectionKey ) }
165
- fields={ this.getSectionFields( sectionKey ) }
166
- onChange={ this.handleSettingChange( sectionKey ) }
167
- onUpdate={ this.handleSectionUpdate( sectionKey ) }
168
- />
169
- ) ) }
176
+ <div
177
+ className={ classnames( 'newspack-plugin-settings', {
178
+ 'newspack-wizard-section__is-loading': inFlight && ! Object.keys( settings ).length,
179
+ } ) }
180
+ >
181
+ { Object.keys( settings ).map( sectionKey => (
182
+ <SettingsSection
183
+ key={ sectionKey }
184
+ disabled={ inFlight }
185
+ sectionKey={ sectionKey }
186
+ title={ this.getSectionTitle( sectionKey ) }
187
+ description={ this.getSectionDescription( sectionKey ) }
188
+ active={ this.isSectionActive( sectionKey ) }
189
+ fields={ this.getSectionFields( sectionKey ) }
190
+ onChange={ this.handleSettingChange( sectionKey ) }
191
+ onUpdate={ this.handleSectionUpdate( sectionKey ) }
192
+ hasGreyHeader={ hasGreyHeader }
193
+ />
194
+ ) ) }
195
+ { children }
196
+ </div>
170
197
  </Fragment>
171
198
  );
172
199
  }
@@ -0,0 +1,7 @@
1
+ .newspack-card:not( .newspack-settings__no-border ) {
2
+ .newspack-action-card__region-children {
3
+ > .newspack-grid {
4
+ margin: 32px 0 0 !important;
5
+ }
6
+ }
7
+ }
@@ -51,15 +51,27 @@ class PluginToggle extends Component {
51
51
  pluginInfo: { ...pluginInfo, [ plugin ]: { ...pluginInfo[ plugin ], inFlight: action } },
52
52
  },
53
53
  () => {
54
- apiFetch( params ).then( response => {
55
- const { shouldRefreshAfterUpdate } = plugins[ plugin ];
56
- this.setState(
57
- ( { pluginInfo: currentPluginInfo } ) => ( {
58
- pluginInfo: { ...currentPluginInfo, [ plugin ]: response },
59
- } ),
60
- () => shouldRefreshAfterUpdate && location.reload()
61
- );
62
- } );
54
+ apiFetch( params )
55
+ .then( response => {
56
+ const { shouldRefreshAfterUpdate } = plugins[ plugin ];
57
+ this.setState(
58
+ ( { pluginInfo: currentPluginInfo } ) => ( {
59
+ pluginInfo: { ...currentPluginInfo, [ plugin ]: response },
60
+ } ),
61
+ () => shouldRefreshAfterUpdate && location.reload()
62
+ );
63
+ } )
64
+ .catch( e => {
65
+ this.setState( {
66
+ pluginInfo: {
67
+ ...pluginInfo,
68
+ [ plugin ]: {
69
+ ...pluginInfo[ plugin ],
70
+ error: e.message || __( 'There was an error managing this plugin.', 'newspack' ),
71
+ },
72
+ },
73
+ } );
74
+ } );
63
75
  }
64
76
  );
65
77
  };
@@ -74,6 +86,7 @@ class PluginToggle extends Component {
74
86
  const { name, description, href, slug, editPath } = plugin;
75
87
  const pluginStatus = this.isPluginInstalledAndActive( plugin );
76
88
  const handoff = ! href && pluginStatus && editPath ? slug : null;
89
+ const error = this.errorForPlugin( plugin );
77
90
  return (
78
91
  <ActionCard
79
92
  key={ index }
@@ -86,6 +99,9 @@ class PluginToggle extends Component {
86
99
  toggle
87
100
  toggleChecked={ this.isPluginInstalledAndActive( plugin ) }
88
101
  toggleOnChange={ value => this.managePlugin( slug, value ) }
102
+ notification={ error }
103
+ notificationHTML={ error }
104
+ notificationLevel="error"
89
105
  />
90
106
  );
91
107
  } );
@@ -160,6 +176,16 @@ class PluginToggle extends Component {
160
176
  }
161
177
  };
162
178
 
179
+ /**
180
+ * Get error message for this plugin.
181
+ */
182
+ errorForPlugin = plugin => {
183
+ const { slug } = plugin;
184
+ const { pluginInfo } = this.state;
185
+
186
+ return pluginInfo[ slug ]?.error || null;
187
+ };
188
+
163
189
  /**
164
190
  * Get installation/activation status for a plugin.
165
191
  */
@@ -8,7 +8,7 @@
8
8
  .newspack-popover {
9
9
  .components-popover__content {
10
10
  border: 1px solid $gray-300;
11
- border-radius: 3px;
11
+ border-radius: 2px;
12
12
  box-shadow: 0 4px 8px rgba( black, 0.08 );
13
13
  min-width: 238px;
14
14
 
@@ -31,7 +31,7 @@
31
31
  }
32
32
 
33
33
  &.is-link {
34
- border-radius: 3px;
34
+ border-radius: 2px;
35
35
  padding: 6px 8px;
36
36
  text-decoration: none;
37
37
 
@@ -76,8 +76,7 @@
76
76
  // Multiple Controls
77
77
 
78
78
  + .newspack-select-control,
79
- + .newspack-text-control,
80
- + .newspack-textarea-control {
79
+ + .newspack-text-control {
81
80
  margin-bottom: 32px;
82
81
  margin-top: -16px;
83
82
  }
@@ -5,6 +5,7 @@
5
5
  /**
6
6
  * Internal dependencies
7
7
  */
8
+ import { Grid } from '..';
8
9
  import './style.scss';
9
10
 
10
11
  /**
@@ -12,19 +13,37 @@ import './style.scss';
12
13
  */
13
14
  import classnames from 'classnames';
14
15
 
15
- const SectionHeader = ( { className, description, noMargin, title } ) => {
16
+ const SectionHeader = ( {
17
+ centered,
18
+ className,
19
+ description,
20
+ heading,
21
+ isWhite,
22
+ noMargin,
23
+ title,
24
+ } ) => {
16
25
  const classes = classnames(
17
26
  'newspack-section-header',
27
+ centered && 'newspack-section-header--is-centered',
28
+ isWhite && 'newspack-section-header--is-white',
18
29
  noMargin && 'newspack-section-header--no-margin',
19
30
  className
20
31
  );
32
+
33
+ const HeadingTag = `h${ heading }`;
34
+
21
35
  return (
22
- <div className={ classes }>
23
- <h2>{ title }</h2>
24
- { typeof description === 'string' && <span>{ description }</span> }
25
- { typeof description === 'function' && <span>{ description() }</span> }
26
- </div>
36
+ <Grid columns={ 1 } gutter={ 8 } className={ classes }>
37
+ { typeof title === 'string' && <HeadingTag>{ title }</HeadingTag> }
38
+ { typeof title === 'function' && <HeadingTag>{ title() }</HeadingTag> }
39
+ { typeof description === 'string' && <p>{ description }</p> }
40
+ { typeof description === 'function' && <p>{ description() }</p> }
41
+ </Grid>
27
42
  );
28
43
  };
29
44
 
45
+ SectionHeader.defaultProps = {
46
+ heading: 2,
47
+ };
48
+
30
49
  export default SectionHeader;
@@ -2,14 +2,39 @@
2
2
  * Section Header
3
3
  */
4
4
 
5
+ @import '~@wordpress/base-styles/colors';
6
+
5
7
  .newspack-section-header {
6
8
  margin: 64px 0 32px;
7
9
 
8
10
  &--no-margin,
9
- h2 {
11
+ h1,
12
+ h2,
13
+ h3,
14
+ h4,
15
+ h5,
16
+ h6 {
10
17
  margin: 0 !important;
11
18
  }
12
19
 
20
+ &--is-centered {
21
+ text-align: center;
22
+ }
23
+
24
+ &:not( #{&}--no-margin ) + *:not( #{&} ) {
25
+ margin-top: -16px !important;
26
+ }
27
+
28
+ &#{&}--is-white {
29
+ > * {
30
+ color: white;
31
+ }
32
+ }
33
+
34
+ p {
35
+ color: $gray-700;
36
+ }
37
+
13
38
  .newspack-wizard__content &:first-child {
14
39
  margin-top: 32px;
15
40
  }
@@ -7,22 +7,30 @@ import classnames from 'classnames';
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { Icon } from '@wordpress/icons';
10
- import { BaseControl } from '@wordpress/components';
10
+ import { BaseControl, Button, ButtonGroup } from '@wordpress/components';
11
11
 
12
12
  /**
13
13
  * Internal dependencies
14
14
  */
15
- import { Button, ButtonGroup, hooks } from '..';
15
+ import { hooks } from '..';
16
16
 
17
- const ButtonGroupControl = ( { buttonOptions, onChange, value, label, className } ) => {
17
+ const ButtonGroupControl = ( {
18
+ buttonOptions,
19
+ className,
20
+ hideLabelFromVision,
21
+ label,
22
+ onChange,
23
+ value,
24
+ } ) => {
18
25
  const id = hooks.useUniqueId( 'button-group' );
19
26
  return (
20
27
  <BaseControl
21
28
  label={ label }
29
+ hideLabelFromVision={ hideLabelFromVision }
22
30
  id={ id.current }
23
31
  className={ classnames( className, 'components-select-control' ) }
24
32
  >
25
- <ButtonGroup noMargin>
33
+ <ButtonGroup>
26
34
  { buttonOptions.map( option => {
27
35
  const isSelected = value === option.value;
28
36
  let Label = () => option.label;
@@ -33,8 +41,7 @@ const ButtonGroupControl = ( { buttonOptions, onChange, value, label, className
33
41
  return (
34
42
  <Button
35
43
  key={ option.value }
36
- isSecondary={ ! isSelected }
37
- isPressed={ isSelected }
44
+ variant={ isSelected ? 'primary' : null }
38
45
  onClick={ () => onChange( option.value ) }
39
46
  >
40
47
  <Label />