newspack-components 3.1.0 → 4.0.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 (191) hide show
  1. package/colors/colors.module.scss +277 -0
  2. package/copy-styles.js +8 -1
  3. package/dist/cjs/action-card/action-card.d.js +5 -0
  4. package/dist/cjs/action-card/index.js +282 -187
  5. package/dist/cjs/action-card/style.scss +142 -44
  6. package/dist/cjs/autocomplete-tokenfield/index.js +6 -2
  7. package/dist/cjs/box-contrast/index.js +49 -0
  8. package/dist/cjs/button/index.js +1 -1
  9. package/dist/cjs/button-props/button-props.js +41 -0
  10. package/dist/cjs/button-props/index.js +13 -0
  11. package/dist/cjs/color-picker/index.js +11 -0
  12. package/dist/cjs/custom-select-control/style.scss +7 -12
  13. package/dist/cjs/footer/index.js +17 -24
  14. package/dist/cjs/footer/style.scss +0 -36
  15. package/dist/cjs/handoff-message/index.js +0 -3
  16. package/dist/cjs/hooks/useObjectState.js +9 -0
  17. package/dist/cjs/hooks/useObjectState.test.js +5 -5
  18. package/dist/cjs/index.js +7 -21
  19. package/dist/cjs/modal/index.js +4 -1
  20. package/dist/cjs/modal/style.scss +18 -7
  21. package/dist/cjs/newspack-icon/index.js +2 -2
  22. package/dist/cjs/newspack-icon/style.scss +3 -5
  23. package/dist/cjs/notice/index.js +1 -2
  24. package/dist/cjs/notice/style.scss +11 -9
  25. package/dist/cjs/plugin-installer/index.js +3 -3
  26. package/dist/cjs/plugin-settings/SettingsSection.js +2 -0
  27. package/dist/cjs/plugin-settings/index.js +4 -1
  28. package/dist/cjs/plugin-toggle/index.js +2 -0
  29. package/dist/cjs/popover/style.scss +5 -6
  30. package/dist/cjs/progress-bar/index.test.js +1 -2
  31. package/dist/cjs/progress-bar/style.scss +1 -2
  32. package/dist/cjs/proxied-imports/router.js +1 -2
  33. package/dist/cjs/radio-control/style.scss +4 -10
  34. package/dist/cjs/section-header/index.js +21 -1
  35. package/dist/cjs/select-control/ButtonGroupControl.js +2 -0
  36. package/dist/cjs/settings/SettingsCard.js +2 -6
  37. package/dist/cjs/sortable-newsletter-list-control/index.js +7 -5
  38. package/dist/cjs/sortable-newsletter-list-control/style.scss +11 -1
  39. package/dist/cjs/steps-list/style.scss +0 -3
  40. package/dist/cjs/steps-list-item/style.scss +1 -2
  41. package/dist/cjs/style-card/index.js +1 -0
  42. package/dist/cjs/style-card/style.scss +4 -5
  43. package/dist/cjs/style.scss +15 -0
  44. package/dist/cjs/tabbed-navigation/index.js +17 -7
  45. package/dist/cjs/tabbed-navigation/style.scss +2 -6
  46. package/dist/cjs/utils/color.js +35 -0
  47. package/dist/cjs/web-preview/style.scss +11 -11
  48. package/dist/cjs/with-wizard/index.js +80 -3
  49. package/dist/cjs/with-wizard/style.scss +34 -13
  50. package/dist/cjs/with-wizard-screen/index.js +3 -3
  51. package/dist/cjs/with-wizard-screen/style.scss +9 -9
  52. package/dist/cjs/wizard/index.js +38 -13
  53. package/dist/cjs/wizard/store/index.js +13 -5
  54. package/dist/cjs/wizard/store/utils.js +3 -1
  55. package/dist/esm/action-card/action-card.d.js +1 -0
  56. package/dist/esm/action-card/index.js +286 -189
  57. package/dist/esm/action-card/style.scss +142 -44
  58. package/dist/esm/autocomplete-tokenfield/index.js +6 -2
  59. package/dist/esm/box-contrast/index.js +44 -0
  60. package/dist/esm/button/index.js +1 -1
  61. package/dist/esm/button-props/button-props.js +34 -0
  62. package/dist/esm/button-props/index.js +1 -0
  63. package/dist/esm/color-picker/index.js +11 -0
  64. package/dist/esm/custom-select-control/style.scss +7 -12
  65. package/dist/esm/footer/index.js +18 -25
  66. package/dist/esm/footer/style.scss +0 -36
  67. package/dist/esm/handoff-message/index.js +0 -3
  68. package/dist/esm/hooks/useObjectState.js +10 -0
  69. package/dist/esm/hooks/useObjectState.test.js +6 -6
  70. package/dist/esm/index.js +1 -3
  71. package/dist/esm/modal/index.js +4 -1
  72. package/dist/esm/modal/style.scss +18 -7
  73. package/dist/esm/newspack-icon/index.js +2 -2
  74. package/dist/esm/newspack-icon/style.scss +3 -5
  75. package/dist/esm/notice/index.js +1 -2
  76. package/dist/esm/notice/style.scss +11 -9
  77. package/dist/esm/plugin-installer/index.js +3 -3
  78. package/dist/esm/plugin-settings/SettingsSection.js +2 -0
  79. package/dist/esm/plugin-settings/index.js +4 -1
  80. package/dist/esm/plugin-toggle/index.js +2 -0
  81. package/dist/esm/popover/style.scss +5 -6
  82. package/dist/esm/progress-bar/style.scss +1 -2
  83. package/dist/esm/radio-control/style.scss +4 -10
  84. package/dist/esm/section-header/index.js +22 -0
  85. package/dist/esm/select-control/ButtonGroupControl.js +2 -0
  86. package/dist/esm/settings/SettingsCard.js +2 -6
  87. package/dist/esm/sortable-newsletter-list-control/index.js +8 -6
  88. package/dist/esm/sortable-newsletter-list-control/style.scss +11 -1
  89. package/dist/esm/steps-list/style.scss +0 -3
  90. package/dist/esm/steps-list-item/style.scss +1 -2
  91. package/dist/esm/style-card/index.js +1 -0
  92. package/dist/esm/style-card/style.scss +4 -5
  93. package/dist/esm/style.scss +15 -0
  94. package/dist/esm/tabbed-navigation/index.js +17 -7
  95. package/dist/esm/tabbed-navigation/style.scss +2 -6
  96. package/dist/esm/utils/color.js +29 -0
  97. package/dist/esm/web-preview/style.scss +11 -11
  98. package/dist/esm/with-wizard/index.js +81 -4
  99. package/dist/esm/with-wizard/style.scss +34 -13
  100. package/dist/esm/with-wizard-screen/index.js +1 -1
  101. package/dist/esm/with-wizard-screen/style.scss +9 -9
  102. package/dist/esm/wizard/index.js +39 -13
  103. package/dist/esm/wizard/store/index.js +13 -5
  104. package/dist/esm/wizard/store/utils.js +3 -1
  105. package/package.json +1 -1
  106. package/src/accordion/index.js +1 -3
  107. package/src/action-card/action-card.d.ts +40 -0
  108. package/src/action-card/index.js +284 -202
  109. package/src/action-card/style.scss +142 -44
  110. package/src/autocomplete-tokenfield/index.js +3 -2
  111. package/src/autocomplete-with-suggestions/index.js +52 -63
  112. package/src/box-contrast/index.tsx +44 -0
  113. package/src/button/index.tsx +1 -1
  114. package/src/button-card/index.js +1 -12
  115. package/src/card/index.js +1 -11
  116. package/src/category-autocomplete/index.js +4 -19
  117. package/src/color-picker/index.js +11 -7
  118. package/src/custom-select-control/style.scss +7 -12
  119. package/src/footer/index.js +6 -18
  120. package/src/footer/style.scss +0 -36
  121. package/src/form-token-field/index.js +1 -2
  122. package/src/grid/index.tsx +1 -8
  123. package/src/handoff/index.js +4 -11
  124. package/src/handoff-message/index.js +0 -3
  125. package/src/hooks/useObjectState.js +10 -2
  126. package/src/hooks/useObjectState.test.js +14 -14
  127. package/src/image-upload/index.js +3 -23
  128. package/src/index.js +1 -3
  129. package/src/modal/index.js +2 -2
  130. package/src/modal/style.scss +18 -7
  131. package/src/newspack-icon/index.js +3 -14
  132. package/src/newspack-icon/style.scss +3 -5
  133. package/src/notice/index.js +0 -2
  134. package/src/notice/style.scss +11 -9
  135. package/src/plugin-installer/index.js +8 -17
  136. package/src/plugin-settings/SettingsSection.js +3 -7
  137. package/src/plugin-settings/index.js +7 -14
  138. package/src/plugin-toggle/README.md +3 -3
  139. package/src/plugin-toggle/index.js +10 -13
  140. package/src/popover/index.js +1 -5
  141. package/src/popover/style.scss +5 -6
  142. package/src/position-control/index.js +65 -75
  143. package/src/progress-bar/index.js +2 -9
  144. package/src/progress-bar/index.test.js +4 -13
  145. package/src/progress-bar/style.scss +1 -2
  146. package/src/radio-control/style.scss +4 -10
  147. package/src/section-header/index.js +20 -0
  148. package/src/select-control/ButtonGroupControl.js +2 -9
  149. package/src/select-control/GroupedSelectControl.js +1 -9
  150. package/src/select-control/index.js +1 -5
  151. package/src/settings/MinMaxSetting.js +2 -14
  152. package/src/settings/SettingsCard.js +2 -11
  153. package/src/sortable-newsletter-list-control/index.js +10 -26
  154. package/src/sortable-newsletter-list-control/style.scss +11 -1
  155. package/src/steps-list/style.scss +0 -3
  156. package/src/steps-list-item/index.js +1 -4
  157. package/src/steps-list-item/style.scss +1 -2
  158. package/src/style-card/index.js +6 -21
  159. package/src/style-card/style.scss +4 -5
  160. package/src/style.scss +15 -0
  161. package/src/tabbed-navigation/index.js +19 -7
  162. package/src/tabbed-navigation/style.scss +2 -6
  163. package/src/text-control/index.tsx +2 -12
  164. package/src/utils/color.ts +32 -0
  165. package/src/web-preview/style.scss +11 -11
  166. package/src/with-wizard/index.js +67 -16
  167. package/src/with-wizard/style.scss +34 -13
  168. package/src/with-wizard-screen/index.js +1 -1
  169. package/src/with-wizard-screen/style.scss +9 -9
  170. package/src/wizard/components/WizardError.js +2 -7
  171. package/src/wizard/index.js +64 -62
  172. package/src/wizard/store/index.js +8 -10
  173. package/src/wizard/store/utils.js +3 -4
  174. package/dist/cjs/date-range-picker/index.js +0 -39
  175. package/dist/cjs/date-range-picker/style.scss +0 -148
  176. package/dist/cjs/newspack-logo/index.js +0 -54
  177. package/dist/cjs/newspack-logo/style.scss +0 -30
  178. package/dist/cjs/patrons-logo/index.js +0 -77
  179. package/dist/esm/date-range-picker/index.js +0 -31
  180. package/dist/esm/date-range-picker/style.scss +0 -148
  181. package/dist/esm/newspack-logo/index.js +0 -46
  182. package/dist/esm/newspack-logo/style.scss +0 -30
  183. package/dist/esm/patrons-logo/index.js +0 -70
  184. package/shared/scss/_colors.scss +0 -27
  185. package/src/date-range-picker/index.js +0 -31
  186. package/src/date-range-picker/style.scss +0 -148
  187. package/src/newspack-logo/index.js +0 -45
  188. package/src/newspack-logo/style.scss +0 -30
  189. package/src/patrons-logo/index.js +0 -76
  190. /package/{shared/js → src/button-props}/button-props.js +0 -0
  191. /package/{shared/js → src/button-props}/index.js +0 -0
@@ -20,15 +20,7 @@ import { hooks } from '..';
20
20
  /**
21
21
  * SelectControl with optgroup support
22
22
  */
23
- export default function GroupedSelectControl( {
24
- help,
25
- label,
26
- onChange,
27
- optgroups = [],
28
- className,
29
- hideLabelFromVision,
30
- ...props
31
- } ) {
23
+ export default function GroupedSelectControl( { help, label, onChange, optgroups = [], className, hideLabelFromVision, ...props } ) {
32
24
  const onChangeValue = event => {
33
25
  const { value } = event.target;
34
26
  const optgroup = find( optgroups, group => some( group.options, [ 'value', value ] ) );
@@ -38,11 +38,7 @@ class SelectControl extends Component {
38
38
  { optgroups ? (
39
39
  <GroupedSelectControl optgroups={ optgroups } { ...otherProps } />
40
40
  ) : buttonOptions ? (
41
- <ButtonGroupControl
42
- buttonOptions={ buttonOptions }
43
- buttonSmall={ buttonSmall }
44
- { ...otherProps }
45
- />
41
+ <ButtonGroupControl buttonOptions={ buttonOptions } buttonSmall={ buttonSmall } { ...otherProps } />
46
42
  ) : (
47
43
  <BaseComponent { ...otherProps } />
48
44
  ) }
@@ -9,23 +9,11 @@ import { CheckboxControl } from '@wordpress/components';
9
9
  */
10
10
  import { TextControl } from '../';
11
11
 
12
- const MinMaxSetting = ( {
13
- min,
14
- max,
15
- onChangeMin,
16
- onChangeMax,
17
- minPlaceholder,
18
- maxPlaceholder,
19
- ...props
20
- } ) => {
12
+ const MinMaxSetting = ( { min, max, onChangeMin, onChangeMax, minPlaceholder, maxPlaceholder, ...props } ) => {
21
13
  return (
22
14
  <div { ...props }>
23
15
  <div className="newspack-settings__min-max">
24
- <CheckboxControl
25
- checked={ min > 0 }
26
- onChange={ value => onChangeMin( value ? 1 : 0 ) }
27
- label={ __( 'Min', 'newspack-plugin' ) }
28
- />
16
+ <CheckboxControl checked={ min > 0 } onChange={ value => onChangeMin( value ? 1 : 0 ) } label={ __( 'Min', 'newspack-plugin' ) } />
29
17
  <TextControl
30
18
  data-testid="min"
31
19
  type="number"
@@ -8,12 +8,8 @@ import classnames from 'classnames';
8
8
  */
9
9
  import { Grid, ActionCard } from '../';
10
10
 
11
- const SettingsCard = ( { children, className, columns, gutter, noBorder, rowGap, ...props } ) => {
12
- const classes = classnames(
13
- 'newspack-settings__card',
14
- noBorder && 'newspack-settings__no-border',
15
- className
16
- );
11
+ const SettingsCard = ( { children, className, columns = 3, gutter = 32, noBorder, rowGap, ...props } ) => {
12
+ const classes = classnames( 'newspack-settings__card', noBorder && 'newspack-settings__no-border', className );
17
13
 
18
14
  return (
19
15
  <ActionCard { ...props } className={ classes } notificationLevel="info" noBorder={ noBorder }>
@@ -24,9 +20,4 @@ const SettingsCard = ( { children, className, columns, gutter, noBorder, rowGap,
24
20
  );
25
21
  };
26
22
 
27
- SettingsCard.defaultProps = {
28
- columns: 3,
29
- gutter: 32,
30
- };
31
-
32
23
  export default SettingsCard;
@@ -2,7 +2,7 @@
2
2
  * WordPress dependencies
3
3
  */
4
4
  import { Icon, chevronUp, chevronDown, trash } from '@wordpress/icons';
5
- import { Notice } from '@wordpress/components';
5
+ import { CheckboxControl, Notice } from '@wordpress/components';
6
6
  import { __ } from '@wordpress/i18n';
7
7
 
8
8
  /**
@@ -12,11 +12,7 @@ import ActionCard from '../action-card';
12
12
  import Button from '../button';
13
13
  import './style.scss';
14
14
 
15
- export default function SortableNewsletterListControl( {
16
- lists,
17
- selected = [],
18
- onChange = () => {},
19
- } ) {
15
+ export default function SortableNewsletterListControl( { lists, selected = [], onChange = () => {} } ) {
20
16
  if ( ! Array.isArray( lists ) && lists.errors ) {
21
17
  return (
22
18
  <Notice status="error" isDismissible={ false }>
@@ -42,8 +38,8 @@ export default function SortableNewsletterListControl( {
42
38
  title={ list.name }
43
39
  description={ () => (
44
40
  <>
45
- <input
46
- type="checkbox"
41
+ <CheckboxControl
42
+ label={ __( 'Checked by default', 'newspack-plugin' ) }
47
43
  checked={ selectedList.checked }
48
44
  onChange={ () => {
49
45
  const index = selected.findIndex( ( { id } ) => id === selectedList.id );
@@ -52,18 +48,17 @@ export default function SortableNewsletterListControl( {
52
48
  onChange( newSelected );
53
49
  } }
54
50
  />
55
- { __( 'Checked by default', 'newspack-plugin' ) }
56
51
  </>
57
52
  ) }
58
53
  isSmall
54
+ hasWhiteHeader
59
55
  actionText={
60
56
  <>
61
57
  <Button
62
- onClick={ () =>
63
- onChange( selected.filter( ( { id } ) => id !== selectedList.id ) )
64
- }
58
+ onClick={ () => onChange( selected.filter( ( { id } ) => id !== selectedList.id ) ) }
65
59
  label={ __( 'Remove', 'newspack-plugin' ) }
66
60
  icon={ trash }
61
+ isDestructive
67
62
  />
68
63
  </>
69
64
  }
@@ -81,11 +76,7 @@ export default function SortableNewsletterListControl( {
81
76
  newSelected.splice( index - 1, 0, selectedList );
82
77
  onChange( newSelected );
83
78
  } }
84
- className={
85
- selected.findIndex( ( { id } ) => id === selectedList.id ) === 0
86
- ? 'disabled'
87
- : ''
88
- }
79
+ className={ selected.findIndex( ( { id } ) => id === selectedList.id ) === 0 ? 'disabled' : '' }
89
80
  >
90
81
  <Icon icon={ chevronUp } />
91
82
  </button>
@@ -98,10 +89,7 @@ export default function SortableNewsletterListControl( {
98
89
  onChange( newSelected );
99
90
  } }
100
91
  className={
101
- selected.findIndex( ( { id } ) => id === selectedList.id ) ===
102
- selected.length - 1
103
- ? 'disabled'
104
- : ''
92
+ selected.findIndex( ( { id } ) => id === selectedList.id ) === selected.length - 1 ? 'disabled' : ''
105
93
  }
106
94
  >
107
95
  <Icon icon={ chevronDown } />
@@ -121,11 +109,7 @@ export default function SortableNewsletterListControl( {
121
109
  ) }{ ' ' }
122
110
  { getAvailableLists().map( list => {
123
111
  return (
124
- <Button
125
- key={ list.id }
126
- variant="secondary"
127
- onClick={ () => onChange( [ ...selected, { id: list.id, checked: true } ] ) }
128
- >
112
+ <Button key={ list.id } variant="secondary" onClick={ () => onChange( [ ...selected, { id: list.id, checked: true } ] ) }>
129
113
  { list.name }
130
114
  </Button>
131
115
  );
@@ -1,10 +1,15 @@
1
1
  .newspack__newsletter-list-control {
2
+ grid-column: span 3;
3
+
2
4
  &__selected {
3
5
  .newspack-card {
4
6
  display: flex;
5
7
  justify-content: center;
6
8
  min-height: 40px;
7
9
  flex-direction: row;
10
+ &:first-of-type {
11
+ margin-top: 0 !important;
12
+ }
8
13
  .newspack-action-card__region {
9
14
  align-items: center;
10
15
  display: flex;
@@ -14,11 +19,16 @@
14
19
  .newspack-action-card__region-top {
15
20
  flex: 1;
16
21
  order: 2;
22
+
23
+ .newspack-grid {
24
+ margin: 0;
25
+ }
17
26
  }
18
27
  .newspack-action-card__region-children {
19
- padding: 12px;
28
+ padding: 12px !important;
20
29
  }
21
30
  }
31
+
22
32
  }
23
33
  &__sort-handle {
24
34
  display: flex;
@@ -1,6 +1,3 @@
1
- @use "../../../shared/scss/colors";
2
- @use "~@wordpress/base-styles/colors" as wp-colors;
3
-
4
1
  .steps-list {
5
2
  margin-left: auto;
6
3
  margin-right: auto;
@@ -28,10 +28,7 @@ class StepsListItem extends Component {
28
28
  return (
29
29
  <div className={ classes } style={ style }>
30
30
  <div className="steps-list-item__number">{ listItemCount }</div>
31
- <div
32
- className="steps-list-item__content"
33
- dangerouslySetInnerHTML={ { __html: listItemText } }
34
- />
31
+ <div className="steps-list-item__content" dangerouslySetInnerHTML={ { __html: listItemText } } />
35
32
  </div>
36
33
  );
37
34
  }
@@ -1,4 +1,3 @@
1
- @use "../../../shared/scss/colors";
2
1
  @use "~@wordpress/base-styles/colors" as wp-colors;
3
2
 
4
3
  .steps-list-item {
@@ -35,7 +34,7 @@
35
34
  background: #fff;
36
35
  border: 1px solid currentcolor;
37
36
  border-radius: 100%;
38
- color: colors.$primary-500;
37
+ color: var(--wp-admin-theme-color);
39
38
  display: flex;
40
39
  height: 28px;
41
40
  justify-content: center;
@@ -25,45 +25,30 @@ class StyleCard extends Component {
25
25
  * Render.
26
26
  */
27
27
  render() {
28
- const { ariaLabel, className, cardTitle, url, image, imageType, isActive, onClick, id } =
29
- this.props;
30
- const classes = classnames(
31
- 'newspack-style-card',
32
- isActive && 'newspack-style-card__is-active',
33
- className
34
- );
28
+ const { ariaLabel, className, cardTitle, url, image, imageType, isActive, onClick, id } = this.props;
29
+ const classes = classnames( 'newspack-style-card', isActive && 'newspack-style-card__is-active', className );
35
30
  return (
36
31
  <div className={ classes } id={ id }>
37
32
  <div className="newspack-style-card__image">
38
33
  { imageType === 'html' ? (
39
- <div dangerouslySetInnerHTML={ image } />
34
+ <div className="newspack-style-card__image-html" dangerouslySetInnerHTML={ image } />
40
35
  ) : (
41
36
  <img src={ image } alt={ cardTitle + ' ' + __( 'Thumbnail', 'newspack-plugin' ) } />
42
37
  ) }
43
38
  <div className="newspack-style-card__actions">
44
39
  { isActive ? (
45
- <span className="newspack-style-card__actions__badge">
46
- { __( 'Selected', 'newspack-plugin' ) }
47
- </span>
40
+ <span className="newspack-style-card__actions__badge">{ __( 'Selected', 'newspack-plugin' ) }</span>
48
41
  ) : (
49
42
  <Button
50
43
  variant="link"
51
44
  onClick={ onClick }
52
- aria-label={
53
- ariaLabel ? ariaLabel : __( 'Select', 'newspack-plugin' ) + ' ' + cardTitle
54
- }
45
+ aria-label={ ariaLabel ? ariaLabel : __( 'Select', 'newspack-plugin' ) + ' ' + cardTitle }
55
46
  tabIndex="0"
56
47
  >
57
48
  { __( 'Select', 'newspack-plugin' ) }
58
49
  </Button>
59
50
  ) }
60
- { url && (
61
- <WebPreview
62
- url={ url }
63
- label={ __( 'View Demo', 'newspack-plugin' ) }
64
- variant="link"
65
- />
66
- ) }
51
+ { url && <WebPreview url={ url } label={ __( 'View Demo', 'newspack-plugin' ) } variant="link" /> }
67
52
  </div>
68
53
  </div>
69
54
  { cardTitle && <div className="newspack-style-card__title">{ cardTitle }</div> }
@@ -2,7 +2,6 @@
2
2
  * Style Card
3
3
  */
4
4
 
5
- @use "../../../shared/scss/colors";
6
5
  @use "~@wordpress/base-styles/colors" as wp-colors;
7
6
 
8
7
  .newspack-style-card {
@@ -15,7 +14,7 @@
15
14
  text-align: center;
16
15
 
17
16
  .newspack-style-card__is-active & {
18
- color: colors.$primary-500;
17
+ color: var(--wp-admin-theme-color);
19
18
  }
20
19
  }
21
20
 
@@ -48,8 +47,8 @@
48
47
  }
49
48
 
50
49
  .newspack-style-card__is-active & {
51
- border-color: colors.$primary-500;
52
- box-shadow: inset 0 0 0 1px colors.$primary-500;
50
+ border-color: var(--wp-admin-theme-color);
51
+ box-shadow: inset 0 0 0 1px var(--wp-admin-theme-color);
53
52
 
54
53
  img {
55
54
  position: relative;
@@ -88,7 +87,7 @@
88
87
  }
89
88
 
90
89
  .newspack-style-card__is-active & {
91
- box-shadow: inset 0 0 0 1px colors.$primary-500;
90
+ box-shadow: inset 0 0 0 1px var(--wp-admin-theme-color);
92
91
  }
93
92
  }
94
93
  }
package/src/style.scss CHANGED
@@ -1,4 +1,15 @@
1
1
  @use "~@wordpress/base-styles/colors" as wp-colors;
2
+ @use "../../colors/colors.module" as colors;
3
+
4
+ :root {
5
+ // WP Admin
6
+ --wp-admin-theme-color: #{colors.$primary-600};
7
+ --wp-admin-theme-color--rgb: #{colors.$primary-600--rgb};
8
+ --wp-admin-theme-color-darker-10: #{colors.$primary-700};
9
+ --wp-admin-theme-color-darker-10--rgb: #{colors.$primary-700--rgb};
10
+ --wp-admin-theme-color-darker-20: #{colors.$primary-800};
11
+ --wp-admin-theme-color-darker-20--rgb: #{colors.$primary-800--rgb};
12
+ }
2
13
 
3
14
  // Buttons Card
4
15
 
@@ -13,6 +24,10 @@
13
24
  &:empty {
14
25
  display: none;
15
26
  }
27
+
28
+ + .newspack-card {
29
+ margin-top: 64px;
30
+ }
16
31
  }
17
32
 
18
33
  // Checkboxes
@@ -16,6 +16,23 @@ const TabbedNavigation = ( { items, className, disableUpcoming, children = null
16
16
  const displayedItems = items.filter( item => ! item.isHiddenInTabbedNavigation );
17
17
  const { location } = useHistory();
18
18
  const currentIndex = findIndex( displayedItems, [ 'path', location.pathname ] );
19
+
20
+ function isActive( item, match, pathname ) {
21
+ if ( item.path === pathname ) {
22
+ return true;
23
+ }
24
+ if ( Array.isArray( item?.activeTabPaths ) ) {
25
+ return item.activeTabPaths.some( path => {
26
+ if ( path.endsWith( '*' ) ) {
27
+ const basePath = path.slice( 0, -1 );
28
+ return pathname.startsWith( basePath );
29
+ }
30
+ return item.activeTabPaths.includes( pathname );
31
+ } );
32
+ }
33
+ return match;
34
+ }
35
+
19
36
  return (
20
37
  <div className={ classnames( 'newspack-tabbed-navigation', className ) }>
21
38
  <ul>
@@ -23,13 +40,8 @@ const TabbedNavigation = ( { items, className, disableUpcoming, children = null
23
40
  <li key={ index }>
24
41
  <NavLink
25
42
  to={ item.path }
26
- isActive={ ( match, { pathname } ) => {
27
- if ( item.activeTabPaths ) {
28
- return item.activeTabPaths.includes( pathname );
29
- }
30
- return match;
31
- } }
32
- exact
43
+ isActive={ ( match, { pathname } ) => isActive( item, match, pathname ) }
44
+ exact={ item.hasOwnProperty( 'exact' ) ? item.exact : true }
33
45
  activeClassName={ 'selected' }
34
46
  className={ classnames( {
35
47
  disabled: disableUpcoming && index > currentIndex,
@@ -39,6 +39,7 @@
39
39
  display: flex;
40
40
  font-weight: bold;
41
41
  height: 48px;
42
+ outline: none;
42
43
  padding: 12px 15px;
43
44
  text-decoration: none;
44
45
 
@@ -51,15 +52,10 @@
51
52
  &:focus,
52
53
  &:hover {
53
54
  color: var(--wp-admin-theme-color);
54
- outline: none;
55
- }
56
-
57
- &:focus {
58
- box-shadow: none;
59
55
  }
60
56
 
61
57
  &:focus-visible {
62
- outline: 2px solid;
58
+ outline: 2px solid var(--wp-admin-theme-color);
63
59
  outline-offset: -2px;
64
60
  }
65
61
 
@@ -24,13 +24,7 @@ type BaseComponentProps = {
24
24
  value: string | number;
25
25
  };
26
26
 
27
- const TextControl = ( {
28
- className = '',
29
- required = false,
30
- isWide = false,
31
- withMargin = true,
32
- ...otherProps
33
- } ) => {
27
+ const TextControl = ( { className = '', required = false, isWide = false, withMargin = true, ...otherProps } ) => {
34
28
  const wrapperRef = useRef< HTMLDivElement >( null );
35
29
  useEffect( () => {
36
30
  if ( wrapperRef.current === null ) {
@@ -51,11 +45,7 @@ const TextControl = ( {
51
45
  );
52
46
  return required ? (
53
47
  <div ref={ wrapperRef } className="newspack-text-control--required">
54
- <BaseComponent
55
- className={ classes }
56
- required={ required }
57
- { ...( otherProps as BaseComponentProps ) }
58
- />
48
+ <BaseComponent className={ classes } required={ required } { ...( otherProps as BaseComponentProps ) } />
59
49
  </div>
60
50
  ) : (
61
51
  <BaseComponent className={ classes } { ...( otherProps as BaseComponentProps ) } />
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Determine if black or white should be used based on a contrast ratio.
3
+ *
4
+ * @param hexcolor Hex code for determining contrast
5
+ * @return black or white string
6
+ */
7
+ export function getContrast( hexcolor: string ) {
8
+ if ( hexcolor.charAt( 0 ) === '#' ) {
9
+ hexcolor = hexcolor.slice( 1 );
10
+ }
11
+
12
+ // Normalize to 6 character hex code if needed
13
+ if ( hexcolor.length === 3 ) {
14
+ hexcolor = hexcolor
15
+ .split( '' )
16
+ .map( function ( hex ) {
17
+ return hex + hex;
18
+ } )
19
+ .join( '' );
20
+ }
21
+
22
+ // Convert to RGB value
23
+ const r = parseInt( hexcolor.substring( 0, 2 ), 16 );
24
+ const g = parseInt( hexcolor.substring( 2, 4 ), 16 );
25
+ const b = parseInt( hexcolor.substring( 4 ), 16 );
26
+
27
+ // Get YIQ ratio
28
+ const yiq = ( r * 299 + g * 587 + b * 114 ) / 1000;
29
+
30
+ // Check contrast
31
+ return yiq >= 128 ? 'black' : 'white';
32
+ }
@@ -2,19 +2,19 @@
2
2
  * Web Preview
3
3
  */
4
4
 
5
- @use "../../../shared/scss/colors";
6
5
  @use "~@wordpress/base-styles/colors" as wp-colors;
6
+ @use "../../../colors/colors.module" as colors;
7
7
 
8
8
  .newspack-web-preview {
9
9
  // Color
10
- --wp-admin-theme-color: #{colors.$primary-500};
11
- --wp-admin-theme-color--rgb: #{colors.$primary-500--rgb};
12
- --wp-admin-theme-color-darker-10: #{colors.$primary-600};
13
- --wp-admin-theme-color-darker-10--rgb: #{colors.$primary-600--rgb};
14
- --wp-admin-theme-color-darker-20: #{colors.$primary-700};
15
- --wp-admin-theme-color-darker-20--rgb: #{colors.$primary-700--rgb};
16
-
17
- background: rgba(black, 0.7);
10
+ --wp-admin-theme-color: #{colors.$primary-600};
11
+ --wp-admin-theme-color--rgb: #{colors.$primary-600--rgb};
12
+ --wp-admin-theme-color-darker-10: #{colors.$primary-700};
13
+ --wp-admin-theme-color-darker-10--rgb: #{colors.$primary-700--rgb};
14
+ --wp-admin-theme-color-darker-20: #{colors.$primary-800};
15
+ --wp-admin-theme-color-darker-20--rgb: #{colors.$primary-800--rgb};
16
+
17
+ background: #{colors.$neutral-700};
18
18
  box-sizing: border-box;
19
19
  height: 100%;
20
20
  left: 0;
@@ -102,7 +102,7 @@
102
102
  padding: 0 !important;
103
103
 
104
104
  &.is-selected {
105
- background: colors.$primary-500;
105
+ background: var(--wp-admin-theme-color);
106
106
  color: white;
107
107
 
108
108
  &:active,
@@ -114,7 +114,7 @@
114
114
  }
115
115
 
116
116
  &:focus {
117
- box-shadow: inset 0 0 0 1px colors.$primary-500, inset 0 0 0 3px white !important;
117
+ box-shadow: inset 0 0 0 1px var(--wp-admin-theme-color), inset 0 0 0 3px white !important;
118
118
  }
119
119
  }
120
120
 
@@ -4,7 +4,7 @@
4
4
  import { Component, createRef, Fragment } from '@wordpress/element';
5
5
  import { __ } from '@wordpress/i18n';
6
6
  import apiFetch from '@wordpress/api-fetch';
7
- import { home } from '@wordpress/icons';
7
+ import { category } from '@wordpress/icons';
8
8
 
9
9
  /**
10
10
  * Internal dependencies.
@@ -28,6 +28,7 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
28
28
  error: null,
29
29
  loading: requiredPlugins && requiredPlugins.length > 0 ? 1 : 0,
30
30
  quietLoading: false,
31
+ confirmation: null,
31
32
  };
32
33
  this.wrappedComponentRef = createRef();
33
34
  }
@@ -80,9 +81,7 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
80
81
  */
81
82
  getErrorNotice = error => {
82
83
  const { message } = error;
83
- return (
84
- <Notice isError className="newspack-wizard__above-header" noticeText={ message } rawHTML />
85
- );
84
+ return <Notice isError className="newspack-wizard__above-header" noticeText={ message } rawHTML />;
86
85
  };
87
86
 
88
87
  /**
@@ -98,10 +97,7 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
98
97
  }
99
98
  const { message } = error;
100
99
  return (
101
- <Modal
102
- title={ __( 'Unrecoverable error' ) }
103
- onRequestClose={ () => ( window.location = fallbackURL ) }
104
- >
100
+ <Modal title={ __( 'Unrecoverable error' ) } onRequestClose={ () => ( window.location = fallbackURL ) }>
105
101
  <Notice noticeText={ message } isError rawHTML />
106
102
  <Card buttonsCard noBorder className="justify-end">
107
103
  <Button isPrimary href={ fallbackURL }>
@@ -221,7 +217,7 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
221
217
  href={ newspack_urls.dashboard }
222
218
  label={ __( 'Return to Dashboard', 'newspack-plugin' ) }
223
219
  showTooltip={ true }
224
- icon={ home }
220
+ icon={ category }
225
221
  iconSize={ 36 }
226
222
  >
227
223
  <NewspackIcon size={ 36 } />
@@ -238,10 +234,7 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
238
234
  </div>
239
235
  ) }
240
236
  <div className="newspack-wizard newspack-wizard__content">
241
- <PluginInstaller
242
- plugins={ requiredPlugins }
243
- onStatus={ status => this.pluginInstallationStatus( status ) }
244
- />
237
+ <PluginInstaller plugins={ requiredPlugins } onStatus={ status => this.pluginInstallationStatus( status ) } />
245
238
  </div>
246
239
  </Fragment>
247
240
  ) }
@@ -249,6 +242,64 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
249
242
  );
250
243
  };
251
244
 
245
+ /**
246
+ * Build a confirmation modal with the given title & message.
247
+ * Execute {callback} if confirmed.
248
+ *
249
+ * @property {Object} options Options for the confirmation modal.
250
+ * @property {string} options.title The title for the modal component.
251
+ * @property {string} options.message The message for the modal component body.
252
+ * @property {string} options.confirmText The text for the confirmation button.
253
+ * @property {string} options.cancelText The text for the cancel button.
254
+ * @property {Function} options.callback A function to call if the user confirms the action.
255
+ */
256
+ confirmAction = options => {
257
+ const modalOptions = {
258
+ title: null,
259
+ message: __( 'Are you sure?', 'newpack-plugin' ),
260
+ confirmText: __( 'OK', 'newspack-plugin' ),
261
+ cancelText: __( 'Cancel', 'newspack-plugin' ),
262
+ callback: null,
263
+ ...options,
264
+ };
265
+ this.setState( { confirmation: modalOptions } );
266
+ };
267
+
268
+ /**
269
+ * Show a confirmation modal with the given title & message.
270
+ * Execute {callback} if confirmed.
271
+ *
272
+ * @return {Component} <Modal>
273
+ */
274
+ getModal = () => {
275
+ if ( ! this.state.confirmation ) {
276
+ return null;
277
+ }
278
+ const { title, message, confirmText, cancelText, callback } = this.state.confirmation;
279
+ return (
280
+ message &&
281
+ callback && (
282
+ <Modal isNarrow hideTitle={ ! title } title={ title } onRequestClose={ () => this.setState( { confirmation: null } ) }>
283
+ <p>{ message }</p>
284
+ <Card buttonsCard noBorder className="justify-end">
285
+ <Button variant="secondary" onClick={ () => this.setState( { confirmation: null } ) }>
286
+ { cancelText }
287
+ </Button>
288
+ <Button
289
+ variant="primary"
290
+ onClick={ () => {
291
+ this.setState( { confirmation: null } );
292
+ callback();
293
+ } }
294
+ >
295
+ { confirmText }
296
+ </Button>
297
+ </Card>
298
+ </Modal>
299
+ )
300
+ );
301
+ };
302
+
252
303
  getFallbackURL = () => {
253
304
  if ( typeof newspack_urls !== 'undefined' ) {
254
305
  return newspack_urls.dashboard;
@@ -261,17 +312,17 @@ export default function withWizard( WrappedComponent, requiredPlugins ) {
261
312
  render() {
262
313
  const { simpleFooter } = this.props;
263
314
  const { loading, quietLoading, error } = this.state;
264
- const loadingClasses = [
265
- loading ? 'newspack-wizard__is-loading' : 'newspack-wizard__is-loaded',
266
- ];
315
+ const loadingClasses = [ loading ? 'newspack-wizard__is-loading' : 'newspack-wizard__is-loaded' ];
267
316
  if ( quietLoading ) {
268
317
  loadingClasses.push( 'newspack-wizard__is-loading-quiet' );
269
318
  }
270
319
  return (
271
320
  <Fragment>
272
321
  { this.getError() }
322
+ { this.getModal() }
273
323
  <div className={ loadingClasses.join( ' ' ) }>
274
324
  <WrappedComponent
325
+ confirmAction={ this.confirmAction }
275
326
  pluginRequirements={ requiredPlugins && this.pluginRequirements() }
276
327
  clearError={ this.clearError }
277
328
  getError={ this.getError }