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
@@ -5,14 +5,16 @@
5
5
  /**
6
6
  * WordPress dependencies
7
7
  */
8
- import { Component } from '@wordpress/element';
9
- import { ExternalLink, ToggleControl } from '@wordpress/components';
10
- import { Icon, check, chevronDown, chevronUp } from '@wordpress/icons';
8
+ import { Draggable, ExternalLink, ToggleControl } from '@wordpress/components';
9
+ import { useEffect, useState } from '@wordpress/element';
10
+ import { __ } from '@wordpress/i18n';
11
+ import { Icon, check, chevronDown, chevronUp, dragHandle } from '@wordpress/icons';
11
12
 
12
13
  /**
13
14
  * Internal dependencies
14
15
  */
15
16
  import { Button, Card, Grid, Handoff, Notice, Waiting } from '../';
17
+ import { ActionCardProps } from './action-card.d.ts';
16
18
  import './style.scss';
17
19
 
18
20
  /**
@@ -20,223 +22,303 @@ import './style.scss';
20
22
  */
21
23
  import classnames from 'classnames';
22
24
 
23
- class ActionCard extends Component {
24
- state = {
25
- expanded: false,
26
- };
25
+ /**
26
+ * ActionCard component
27
+ * @param {ActionCardProps} props Component props.
28
+ * @return {JSX.Element} ActionCard component.
29
+ */
30
+ const ActionCard = ( {
31
+ badge,
32
+ badgeLevel = 'info',
33
+ className,
34
+ checkbox,
35
+ children,
36
+ collapse,
37
+ disabled,
38
+ title,
39
+ description,
40
+ handoff,
41
+ editLink,
42
+ href,
43
+ notification,
44
+ notificationLevel,
45
+ notificationHTML,
46
+ actionContent,
47
+ actionText,
48
+ secondaryActionText,
49
+ secondaryDestructive,
50
+ id,
51
+ image,
52
+ imageLink,
53
+ indent,
54
+ isSmall,
55
+ isMedium,
56
+ simple,
57
+ onClick,
58
+ onSecondaryActionClick,
59
+ isWaiting,
60
+ titleLink,
61
+ toggleChecked = false,
62
+ toggleOnChange,
63
+ hasGreyHeader,
64
+ hasWhiteHeader,
65
+ noBorder,
66
+ isPending,
67
+ expandable = false,
68
+ isButtonEnabled = false,
69
+ // Draggable props. All are required to enable drag sorting.
70
+ draggable = false,
71
+ dragIndex,
72
+ dragWrapperRef,
73
+ onDragCallback,
74
+ } ) => {
75
+ const [ expanded, setExpanded ] = useState( false );
76
+ const [ dragging, setDragging ] = useState( false );
77
+ const [ targetIndex, setTargetIndex ] = useState( null );
78
+ const [ dragRef, setDragRef ] = useState( null );
27
79
 
28
- /**
29
- * When the collapse prop is updated to true, collapse the card if already expanded.
30
- */
31
- componentDidUpdate( prevProps ) {
32
- if ( ! prevProps.collapse && this.props.collapse && this.state.expanded ) {
33
- this.setState( { expanded: false } );
80
+ useEffect( () => {
81
+ if ( dragWrapperRef && ! dragRef ) {
82
+ setDragRef( dragWrapperRef );
34
83
  }
35
- }
84
+ }, [ dragWrapperRef?.current ] );
36
85
 
37
- /**
38
- * Render.
39
- */
40
- render() {
41
- const {
42
- badge,
43
- className,
44
- checkbox,
45
- children,
46
- disabled,
47
- title,
48
- description,
49
- handoff,
50
- editLink,
51
- href,
52
- notification,
53
- notificationLevel,
54
- notificationHTML,
55
- actionContent,
56
- actionText,
57
- secondaryActionText,
58
- secondaryDestructive,
59
- image,
60
- imageLink,
61
- indent,
62
- isSmall,
63
- isMedium,
64
- simple,
65
- onClick,
66
- onSecondaryActionClick,
67
- isWaiting,
68
- titleLink,
69
- toggleChecked,
70
- toggleOnChange,
71
- hasGreyHeader,
72
- hasWhiteHeader,
73
- isPending,
74
- expandable = false,
75
- isButtonEnabled = false
76
- } = this.props;
77
-
78
- const { expanded } = this.state;
79
-
80
- const hasChildren = notification || children;
81
- const classes = classnames(
82
- 'newspack-action-card',
83
- simple && 'newspack-card--is-clickable',
84
- hasGreyHeader && 'newspack-card--has-grey-header',
85
- hasWhiteHeader && 'newspack-card--has-white-header',
86
- hasChildren && 'newspack-card--has-children',
87
- indent && 'newspack-card--indent',
88
- isSmall && 'is-small',
89
- isMedium && 'is-medium',
90
- checkbox && 'has-checkbox',
91
- expandable && 'is-expandable',
92
- actionContent && 'has-action-content',
93
- className
94
- );
95
- const backgroundImageStyles = url => {
96
- return url ? { backgroundImage: `url(${ url })` } : {};
97
- };
98
- const titleProps =
99
- toggleOnChange && ! titleLink && ! disabled
100
- ? { onClick: () => toggleOnChange( ! toggleChecked ), tabIndex: '0' }
101
- : {};
102
- const hasInternalLink = href && href.indexOf( 'http' ) !== 0;
103
- const isDisplayingSecondaryAction = secondaryActionText && onSecondaryActionClick;
104
- const badges = ! Array.isArray( badge ) && badge ? [ badge ] : badge;
105
- return (
106
- <Card className={ classes } onClick={ simple && onClick }>
107
- <div className="newspack-action-card__region newspack-action-card__region-top">
108
- { toggleOnChange && (
109
- <ToggleControl
110
- checked={ toggleChecked }
111
- onChange={ toggleOnChange }
112
- disabled={ disabled }
113
- />
114
- ) }
115
- { image && ! toggleOnChange && (
116
- <div className="newspack-action-card__region newspack-action-card__region-left">
117
- <a href={ imageLink }>
118
- <div
119
- className="newspack-action-card__image"
120
- style={ backgroundImageStyles( image ) }
121
- />
122
- </a>
123
- </div>
124
- ) }
125
- { checkbox && ! toggleOnChange && (
126
- <div className="newspack-action-card__region newspack-action-card__region-left">
127
- <span
128
- className={ classnames(
129
- 'newspack-checkbox-icon',
130
- 'is-primary',
131
- 'checked' === checkbox && 'newspack-checkbox-icon--checked',
132
- isPending && 'newspack-checkbox-icon--pending'
133
- ) }
134
- >
135
- { 'checked' === checkbox && <Icon icon={ check } /> }
136
- </span>
137
- </div>
138
- ) }
139
- <div className="newspack-action-card__region newspack-action-card__region-center">
140
- <Grid columns={ 1 } gutter={ 8 } noMargin>
141
- <h2>
142
- <span className="newspack-action-card__title" { ...titleProps }>
143
- { titleLink && <a href={ titleLink }>{ title }</a> }
144
- { ! titleLink && expandable && (
145
- <Button isLink onClick={ () => this.setState( { expanded: ! expanded } ) }>
146
- { title }
147
- </Button>
148
- ) }
149
- { ! titleLink && ! expandable && title }
150
- </span>
151
- { badges?.length &&
152
- badges.map( ( badgeText, i ) => (
153
- <span key={ `badge-${ i }` } className="newspack-action-card__badge">
154
- { badgeText }
155
- </span>
156
- ) ) }
157
- </h2>
158
- { description && (
159
- <p>
160
- { typeof description === 'string' && description }
161
- { typeof description === 'function' && description() }
162
- </p>
86
+ useEffect( () => {
87
+ if ( collapse && expanded ) {
88
+ setExpanded( false );
89
+ }
90
+ }, [ collapse ] );
91
+
92
+ const hasChildren = notification || children;
93
+ const classes = classnames(
94
+ 'newspack-action-card',
95
+ simple && 'newspack-card--is-clickable',
96
+ hasGreyHeader && 'newspack-card--has-grey-header',
97
+ hasWhiteHeader && 'newspack-card--has-white-header',
98
+ hasChildren && 'newspack-card--has-children',
99
+ indent && 'newspack-card--indent',
100
+ isSmall && 'is-small',
101
+ isMedium && 'is-medium',
102
+ checkbox && 'has-checkbox',
103
+ expandable && 'is-expandable',
104
+ draggable && 'is-draggable',
105
+ actionContent && 'has-action-content',
106
+ className
107
+ );
108
+ const backgroundImageStyles = url => {
109
+ return url ? { backgroundImage: `url(${ url })` } : {};
110
+ };
111
+ const titleProps = toggleOnChange && ! titleLink && ! disabled ? { onClick: () => toggleOnChange( ! toggleChecked ), tabIndex: '0' } : {};
112
+ const hasInternalLink = href && href.indexOf( 'http' ) !== 0;
113
+ const isDisplayingSecondaryAction = secondaryActionText && onSecondaryActionClick;
114
+ const badges = ! Array.isArray( badge ) && badge ? [ badge ] : badge;
115
+
116
+ const Component = () => (
117
+ <>
118
+ <div className="newspack-action-card__region newspack-action-card__region-top">
119
+ { toggleOnChange && <ToggleControl checked={ toggleChecked } onChange={ toggleOnChange } disabled={ disabled } /> }
120
+ { image && ! toggleOnChange && (
121
+ <div className="newspack-action-card__region newspack-action-card__region-left">
122
+ <a href={ imageLink }>
123
+ <div className="newspack-action-card__image" style={ backgroundImageStyles( image ) } />
124
+ </a>
125
+ </div>
126
+ ) }
127
+ { checkbox && ! toggleOnChange && (
128
+ <div className="newspack-action-card__region newspack-action-card__region-left">
129
+ <span
130
+ className={ classnames(
131
+ 'newspack-checkbox-icon',
132
+ 'is-primary',
133
+ 'checked' === checkbox && 'newspack-checkbox-icon--checked',
134
+ isPending && 'newspack-checkbox-icon--pending'
163
135
  ) }
164
- </Grid>
136
+ >
137
+ { 'checked' === checkbox && <Icon icon={ check } /> }
138
+ </span>
165
139
  </div>
166
- { ! expandable && ( actionText || isDisplayingSecondaryAction || actionContent ) && (
167
- <div className="newspack-action-card__region newspack-action-card__region-right">
168
- { /* eslint-disable no-nested-ternary */ }
169
- { actionContent && actionContent }
170
- { actionText &&
171
- ( handoff ? (
172
- <Handoff plugin={ handoff } editLink={ editLink } compact isLink>
173
- { actionText }
174
- </Handoff>
175
- ) : onClick || hasInternalLink ? (
176
- <Button
177
- disabled={ disabled && ! isButtonEnabled }
178
- isLink
179
- href={ href }
180
- onClick={ onClick }
181
- className="newspack-action-card__primary_button"
182
- >
183
- { actionText }
140
+ ) }
141
+ <div className="newspack-action-card__region newspack-action-card__region-center">
142
+ <Grid columns={ 1 } gutter={ 8 } noMargin>
143
+ <h2>
144
+ <span className="newspack-action-card__title" { ...titleProps }>
145
+ { titleLink && <a href={ titleLink }>{ title }</a> }
146
+ { ! titleLink && expandable && (
147
+ <Button isLink onClick={ () => setExpanded( ! expanded ) }>
148
+ { title }
184
149
  </Button>
185
- ) : href ? (
186
- <ExternalLink href={ href } className="newspack-action-card__primary_button">
187
- { actionText }
188
- </ExternalLink>
189
- ) : (
190
- <div className="newspack-action-card__container">
191
- { actionText }
192
- { isWaiting && <Waiting isRight /> }
193
- </div>
150
+ ) }
151
+ { ! titleLink && ! expandable && title }
152
+ </span>
153
+ { badges?.length &&
154
+ badges.map( ( badgeText, i ) => (
155
+ <span
156
+ key={ `badge-${ i }` }
157
+ className={ `newspack-action-card__badge newspack-action-card__badge-level-${ badgeLevel }` }
158
+ >
159
+ { badgeText }
160
+ </span>
194
161
  ) ) }
195
- { /* eslint-enable no-nested-ternary */ }
196
- { isDisplayingSecondaryAction && (
162
+ </h2>
163
+ { description && (
164
+ <p>
165
+ { typeof description === 'string' && description }
166
+ { typeof description === 'function' && description() }
167
+ </p>
168
+ ) }
169
+ </Grid>
170
+ </div>
171
+ { ! expandable && ( actionText || isDisplayingSecondaryAction || actionContent ) && (
172
+ <div className="newspack-action-card__region newspack-action-card__region-right">
173
+ { /* eslint-disable no-nested-ternary */ }
174
+ { actionContent && actionContent }
175
+ { actionText &&
176
+ ( handoff ? (
177
+ <Handoff plugin={ handoff } editLink={ editLink } compact isLink>
178
+ { actionText }
179
+ </Handoff>
180
+ ) : onClick || hasInternalLink ? (
197
181
  <Button
182
+ disabled={ disabled && ! isButtonEnabled }
198
183
  isLink
199
- onClick={ onSecondaryActionClick }
200
- className="newspack-action-card__secondary_button"
201
- isDestructive={ secondaryDestructive }
184
+ href={ href }
185
+ onClick={ onClick }
186
+ className="newspack-action-card__primary_button"
202
187
  >
203
- { secondaryActionText }
188
+ { actionText }
204
189
  </Button>
205
- ) }
206
- </div>
207
- ) }
208
- { expandable && (
209
- <Button onClick={ () => this.setState( { expanded: ! expanded } ) }>
210
- <Icon icon={ expanded ? chevronUp : chevronDown } height={ 24 } width={ 24 } />
211
- </Button>
212
- ) }
213
- </div>
214
- { notification && (
215
- <div className="newspack-action-card__notification newspack-action-card__region-children">
216
- { 'error' === notificationLevel && (
217
- <Notice noticeText={ notification } isError rawHTML={ notificationHTML } />
218
- ) }
219
- { 'info' === notificationLevel && (
220
- <Notice noticeText={ notification } rawHTML={ notificationHTML } />
221
- ) }
222
- { 'success' === notificationLevel && (
223
- <Notice noticeText={ notification } isSuccess rawHTML={ notificationHTML } />
224
- ) }
225
- { 'warning' === notificationLevel && (
226
- <Notice noticeText={ notification } isWarning rawHTML={ notificationHTML } />
190
+ ) : href ? (
191
+ <ExternalLink href={ href } className="newspack-action-card__primary_button">
192
+ { actionText }
193
+ </ExternalLink>
194
+ ) : (
195
+ <div className="newspack-action-card__container">
196
+ { actionText }
197
+ { isWaiting && <Waiting isRight /> }
198
+ </div>
199
+ ) ) }
200
+ { /* eslint-enable no-nested-ternary */ }
201
+ { isDisplayingSecondaryAction && (
202
+ <Button
203
+ isLink
204
+ onClick={ onSecondaryActionClick }
205
+ className="newspack-action-card__secondary_button"
206
+ isDestructive={ secondaryDestructive }
207
+ >
208
+ { secondaryActionText }
209
+ </Button>
227
210
  ) }
228
211
  </div>
229
212
  ) }
230
- { children && ( ( expandable && expanded ) || ! expandable ) && (
231
- <div className="newspack-action-card__region-children">{ children }</div>
213
+ { expandable && (
214
+ <Button onClick={ () => setExpanded( ! expanded ) }>
215
+ <Icon icon={ expanded ? chevronUp : chevronDown } height={ 24 } width={ 24 } />
216
+ </Button>
232
217
  ) }
233
- </Card>
218
+ </div>
219
+ { notification && (
220
+ <div className="newspack-action-card__notification newspack-action-card__region-children">
221
+ { 'error' === notificationLevel && <Notice noticeText={ notification } isError rawHTML={ notificationHTML } /> }
222
+ { 'info' === notificationLevel && <Notice noticeText={ notification } rawHTML={ notificationHTML } /> }
223
+ { 'success' === notificationLevel && <Notice noticeText={ notification } isSuccess rawHTML={ notificationHTML } /> }
224
+ { 'warning' === notificationLevel && <Notice noticeText={ notification } isWarning rawHTML={ notificationHTML } /> }
225
+ </div>
226
+ ) }
227
+ { children && ( ( expandable && expanded ) || ! expandable ) && (
228
+ <div className="newspack-action-card__region-children">{ children }</div>
229
+ ) }
230
+ </>
231
+ );
232
+
233
+ if ( draggable && dragRef?.current && typeof dragIndex === 'number' && onDragCallback && id ) {
234
+ let wrapperRect = dragRef.current.getBoundingClientRect();
235
+ let draggableCards = Array.prototype.slice.call( dragRef.current.querySelectorAll( '.newspack-action-card__draggable-wrapper' ) );
236
+ const isFirstTarget = dragIndex === 0;
237
+ const isLastTarget = dragIndex === draggableCards.length - 1;
238
+ const handleDragStart = () => {
239
+ draggableCards = Array.prototype.slice.call( dragRef.current.querySelectorAll( '.newspack-action-card__draggable-wrapper' ) );
240
+ wrapperRect = dragRef.current.getBoundingClientRect();
241
+ if ( dragging ) {
242
+ return;
243
+ }
244
+ setTargetIndex( dragIndex );
245
+ setDragging( true );
246
+ };
247
+ const handleDragEnd = () => {
248
+ if ( targetIndex !== null && targetIndex !== dragIndex ) {
249
+ onDragCallback( targetIndex );
250
+ }
251
+ setTargetIndex( null );
252
+ setDragging( false );
253
+ };
254
+ const handleDragOver = e => {
255
+ const isDraggingToTop = e.pageY <= wrapperRect.top + window.scrollY;
256
+ const isDraggingToBottom = e.pageY >= wrapperRect.bottom + window.scrollY;
257
+ const target = e.target.closest( '.newspack-action-card__draggable-wrapper' );
258
+
259
+ if ( isDraggingToTop || isDraggingToBottom || target ) {
260
+ setTargetIndex( draggableCards.indexOf( target ) );
261
+
262
+ // If dragging the element over itself or over an invalid target, cancel the drop.
263
+ if ( 0 > targetIndex || targetIndex === dragIndex + 1 ) {
264
+ setTargetIndex( dragIndex );
265
+ }
266
+
267
+ // Handle dropping before the first item.
268
+ if ( isDraggingToTop ) {
269
+ setTargetIndex( 0 );
270
+ }
271
+
272
+ // Handle dropping after the last item.
273
+ if ( isDraggingToBottom ) {
274
+ setTargetIndex( draggableCards.length );
275
+ }
276
+ }
277
+ };
278
+
279
+ return (
280
+ <div className={ 'newspack-action-card__draggable-wrapper' + ( dragging ? ' is-dragging' : '' ) } id={ `draggable-card-${ id }` }>
281
+ <Draggable
282
+ elementId={ `draggable-card-${ id }` }
283
+ transferData={ {} }
284
+ onDragStart={ handleDragStart }
285
+ onDragEnd={ handleDragEnd }
286
+ onDragOver={ handleDragOver }
287
+ >
288
+ { ( { onDraggableStart, onDraggableEnd } ) => (
289
+ <Card className={ classes } onClick={ simple && onClick } id={ id ?? null } noBorder={ noBorder }>
290
+ <div className="newspack-action-card__draggable-controls">
291
+ <div className="drag-handle" draggable onDragStart={ onDraggableStart } onDragEnd={ onDraggableEnd }>
292
+ <Icon icon={ dragHandle } height={ 18 } width={ 18 } />
293
+ </div>
294
+ <div className="movers">
295
+ <Button
296
+ icon={ chevronUp }
297
+ onClick={ () => onDragCallback( dragIndex - 1 ) }
298
+ disabled={ isFirstTarget }
299
+ label={ __( 'Move one position up', 'newspack-plugin' ) }
300
+ />
301
+ <Button
302
+ icon={ chevronDown }
303
+ onClick={ () => onDragCallback( dragIndex + 1 ) }
304
+ disabled={ isLastTarget }
305
+ label={ __( 'Move one position down', 'newspack-plugin' ) }
306
+ />
307
+ </div>
308
+ </div>
309
+ <Component />
310
+ </Card>
311
+ ) }
312
+ </Draggable>
313
+ </div>
234
314
  );
235
315
  }
236
- }
237
316
 
238
- ActionCard.defaultProps = {
239
- toggleChecked: false,
317
+ return (
318
+ <Card className={ classes } onClick={ simple && onClick } id={ id ?? null } noBorder={ noBorder }>
319
+ <Component />
320
+ </Card>
321
+ );
240
322
  };
241
323
 
242
324
  export default ActionCard;