newspack-components 4.3.0 → 4.4.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/DEVELOPMENT.md +868 -0
- package/colors/colors.module.scss +52 -2
- package/copy-styles.js +3 -2
- package/dist/cjs/accordion/index.js +17 -12
- package/dist/cjs/action-card/index.js +176 -139
- package/dist/cjs/autocomplete-tokenfield/index.js +254 -234
- package/dist/cjs/autocomplete-with-latest-posts/index.js +172 -110
- package/dist/cjs/autocomplete-with-suggestions/index.js +229 -126
- package/dist/cjs/badge/index.js +7 -7
- package/dist/cjs/box-contrast/index.js +19 -15
- package/dist/cjs/button/index.js +41 -26
- package/dist/cjs/button-props/button-props.js +5 -5
- package/dist/cjs/button-props/index.js +2 -2
- package/dist/cjs/card/core-card.js +110 -52
- package/dist/cjs/card/index.js +74 -67
- package/dist/cjs/card/style-core.scss +93 -25
- package/dist/cjs/card/style.scss +2 -2
- package/dist/cjs/card-feature/index.js +141 -0
- package/dist/cjs/card-feature/style.scss +75 -0
- package/dist/cjs/card-form/index.js +144 -0
- package/dist/cjs/card-form/style.scss +20 -0
- package/dist/cjs/card-settings-group/index.js +36 -16
- package/dist/cjs/card-sortable-list/index.js +176 -140
- package/dist/cjs/category-autocomplete/index.js +175 -155
- package/dist/cjs/color-picker/index.js +41 -23
- package/dist/cjs/color-picker/index.test.js +82 -0
- package/dist/cjs/color-picker/style.scss +11 -13
- package/dist/cjs/confirm-dialog/index.js +86 -22
- package/dist/cjs/consts.js +1 -1
- package/dist/cjs/custom-select-control/index.js +39 -28
- package/dist/cjs/dataviews/index.js +38 -0
- package/dist/cjs/dataviews/style.scss +9 -0
- package/dist/cjs/divider/index.js +26 -21
- package/dist/cjs/footer/index.js +36 -30
- package/dist/cjs/form-token-field/index.js +51 -40
- package/dist/cjs/global-notices/index.js +5 -5
- package/dist/cjs/grid/index.js +25 -19
- package/dist/cjs/grid/style.scss +6 -1
- package/dist/cjs/handoff/index.js +204 -156
- package/dist/cjs/handoff-message/index.js +12 -7
- package/dist/cjs/hooks/index.js +10 -8
- package/dist/cjs/hooks/use-confirm-dialog.js +79 -0
- package/dist/cjs/hooks/use-unsaved-changes-dialog.js +144 -0
- package/dist/cjs/hooks/useObjectState.js +21 -12
- package/dist/cjs/hooks/useObjectState.test.js +55 -33
- package/dist/cjs/hooks/useOnClickOutside.js +6 -6
- package/dist/cjs/hooks/usePrompt.js +10 -13
- package/dist/cjs/image-upload/index.js +114 -123
- package/dist/cjs/image-upload/index.test.js +11 -13
- package/dist/cjs/image-upload/style.scss +12 -40
- package/dist/cjs/index.js +136 -104
- package/dist/cjs/info-button/index.js +43 -32
- package/dist/cjs/integration-icons/active-campaign.js +22 -0
- package/dist/cjs/integration-icons/constant-contact.js +28 -0
- package/dist/cjs/integration-icons/fundraise-up.js +25 -0
- package/dist/cjs/integration-icons/index.js +48 -0
- package/dist/cjs/integration-icons/mailchimp.js +19 -0
- package/dist/cjs/integration-icons/salesforce.js +17 -0
- package/dist/cjs/integration-icons/wisepops.js +20 -0
- package/dist/cjs/modal/index.js +22 -19
- package/dist/cjs/modal/style.scss +4 -0
- package/dist/cjs/newspack-icon/index.js +45 -38
- package/dist/cjs/notice/index.js +64 -55
- package/dist/cjs/plugin-installer/index.js +259 -253
- package/dist/cjs/plugin-settings/SettingsSection.js +66 -60
- package/dist/cjs/plugin-settings/index.js +217 -200
- package/dist/cjs/plugin-toggle/index.js +192 -199
- package/dist/cjs/popover/index.js +41 -28
- package/dist/cjs/position-control/index.js +24 -23
- package/dist/cjs/progress-bar/index.js +71 -59
- package/dist/cjs/progress-bar/index.test.js +62 -68
- package/dist/cjs/proxied-imports/router.js +3 -3
- package/dist/cjs/radio-control/index.js +40 -27
- package/dist/cjs/section-header/index.js +103 -58
- package/dist/cjs/section-header/style.scss +31 -11
- package/dist/cjs/select-control/ButtonGroupControl.js +26 -21
- package/dist/cjs/select-control/GroupedSelectControl.js +41 -35
- package/dist/cjs/select-control/index.js +52 -40
- package/dist/cjs/settings/MinMaxSetting.js +30 -20
- package/dist/cjs/settings/SettingsCard.js +20 -17
- package/dist/cjs/settings/SettingsSection.js +22 -21
- package/dist/cjs/settings/index.js +5 -5
- package/dist/cjs/sortable-newsletter-list-control/index.js +78 -57
- package/dist/cjs/steps-list/index.js +44 -34
- package/dist/cjs/steps-list-item/index.js +47 -39
- package/dist/cjs/style-card/index.js +70 -63
- package/dist/cjs/tabbed-navigation/index.js +38 -36
- package/dist/cjs/text-control/index.js +27 -25
- package/dist/cjs/utils/color.js +4 -4
- package/dist/cjs/utils/editor-toolbar-back-button.js +61 -0
- package/dist/cjs/utils/index.js +31 -19
- package/dist/cjs/utils/style.scss +8 -0
- package/dist/cjs/waiting/index.js +48 -37
- package/dist/cjs/web-preview/index.js +217 -211
- package/dist/cjs/with-wizard/index.js +362 -364
- package/dist/cjs/with-wizard/style.scss +4 -54
- package/dist/cjs/with-wizard-screen/index.js +54 -58
- package/dist/cjs/with-wizard-screen/style.scss +41 -3
- package/dist/cjs/wizard/components/WizardError.js +20 -18
- package/dist/cjs/wizard/components/WizardSnackbar.js +26 -23
- package/dist/cjs/wizard/index.js +176 -114
- package/dist/cjs/wizard/store/index.js +171 -123
- package/dist/cjs/wizard/store/utils.js +13 -8
- package/dist/esm/accordion/index.js +14 -9
- package/dist/esm/action-card/index.js +168 -123
- package/dist/esm/autocomplete-tokenfield/index.js +248 -222
- package/dist/esm/autocomplete-with-latest-posts/index.js +169 -103
- package/dist/esm/autocomplete-with-suggestions/index.js +226 -119
- package/dist/esm/badge/index.js +5 -5
- package/dist/esm/box-contrast/index.js +15 -11
- package/dist/esm/button/index.js +39 -21
- package/dist/esm/button-props/button-props.js +1 -1
- package/dist/esm/card/core-card.js +109 -47
- package/dist/esm/card/index.js +69 -54
- package/dist/esm/card/style-core.scss +93 -25
- package/dist/esm/card/style.scss +2 -2
- package/dist/esm/card-feature/index.js +131 -0
- package/dist/esm/card-feature/style.scss +75 -0
- package/dist/esm/card-form/index.js +134 -0
- package/dist/esm/card-form/style.scss +20 -0
- package/dist/esm/card-settings-group/index.js +33 -14
- package/dist/esm/card-sortable-list/index.js +170 -126
- package/dist/esm/category-autocomplete/index.js +168 -140
- package/dist/esm/color-picker/index.js +39 -21
- package/dist/esm/color-picker/index.test.js +78 -0
- package/dist/esm/color-picker/style.scss +11 -13
- package/dist/esm/confirm-dialog/index.js +85 -18
- package/dist/esm/consts.js +1 -1
- package/dist/esm/custom-select-control/index.js +34 -15
- package/dist/esm/dataviews/index.js +34 -0
- package/dist/esm/dataviews/style.scss +9 -0
- package/dist/esm/divider/index.js +24 -16
- package/dist/esm/footer/index.js +34 -28
- package/dist/esm/form-token-field/index.js +46 -27
- package/dist/esm/global-notices/index.js +3 -3
- package/dist/esm/grid/index.js +23 -14
- package/dist/esm/grid/style.scss +6 -1
- package/dist/esm/handoff/index.js +199 -143
- package/dist/esm/handoff-message/index.js +10 -6
- package/dist/esm/hooks/index.js +8 -6
- package/dist/esm/hooks/use-confirm-dialog.js +73 -0
- package/dist/esm/hooks/use-unsaved-changes-dialog.js +136 -0
- package/dist/esm/hooks/useObjectState.js +19 -9
- package/dist/esm/hooks/useObjectState.test.js +54 -32
- package/dist/esm/hooks/useOnClickOutside.js +4 -4
- package/dist/esm/hooks/usePrompt.js +9 -11
- package/dist/esm/image-upload/index.js +110 -111
- package/dist/esm/image-upload/index.test.js +11 -13
- package/dist/esm/image-upload/style.scss +12 -40
- package/dist/esm/index.js +7 -1
- package/dist/esm/info-button/index.js +38 -19
- package/dist/esm/integration-icons/active-campaign.js +16 -0
- package/dist/esm/integration-icons/constant-contact.js +22 -0
- package/dist/esm/integration-icons/fundraise-up.js +19 -0
- package/dist/esm/integration-icons/index.js +6 -0
- package/dist/esm/integration-icons/mailchimp.js +13 -0
- package/dist/esm/integration-icons/salesforce.js +11 -0
- package/dist/esm/integration-icons/wisepops.js +14 -0
- package/dist/esm/modal/index.js +20 -13
- package/dist/esm/modal/style.scss +4 -0
- package/dist/esm/newspack-icon/index.js +40 -25
- package/dist/esm/notice/index.js +59 -42
- package/dist/esm/plugin-installer/index.js +255 -243
- package/dist/esm/plugin-settings/SettingsSection.js +61 -50
- package/dist/esm/plugin-settings/index.js +212 -189
- package/dist/esm/plugin-toggle/index.js +187 -190
- package/dist/esm/popover/index.js +35 -16
- package/dist/esm/position-control/index.js +22 -18
- package/dist/esm/progress-bar/index.js +66 -49
- package/dist/esm/progress-bar/index.test.js +61 -67
- package/dist/esm/radio-control/index.js +34 -15
- package/dist/esm/section-header/index.js +102 -57
- package/dist/esm/section-header/style.scss +31 -11
- package/dist/esm/select-control/ButtonGroupControl.js +23 -18
- package/dist/esm/select-control/GroupedSelectControl.js +38 -30
- package/dist/esm/select-control/index.js +47 -27
- package/dist/esm/settings/MinMaxSetting.js +27 -16
- package/dist/esm/settings/SettingsCard.js +18 -13
- package/dist/esm/settings/SettingsSection.js +20 -19
- package/dist/esm/settings/index.js +3 -3
- package/dist/esm/sortable-newsletter-list-control/index.js +74 -53
- package/dist/esm/steps-list/index.js +39 -21
- package/dist/esm/steps-list-item/index.js +42 -26
- package/dist/esm/style-card/index.js +65 -50
- package/dist/esm/tabbed-navigation/index.js +35 -33
- package/dist/esm/text-control/index.js +25 -19
- package/dist/esm/utils/color.js +4 -4
- package/dist/esm/utils/editor-toolbar-back-button.js +53 -0
- package/dist/esm/utils/index.js +29 -16
- package/dist/esm/utils/style.scss +8 -0
- package/dist/esm/waiting/index.js +43 -24
- package/dist/esm/web-preview/index.js +213 -201
- package/dist/esm/with-wizard/index.js +360 -358
- package/dist/esm/with-wizard/style.scss +4 -54
- package/dist/esm/with-wizard-screen/index.js +48 -46
- package/dist/esm/with-wizard-screen/style.scss +41 -3
- package/dist/esm/wizard/components/WizardError.js +18 -16
- package/dist/esm/wizard/components/WizardSnackbar.js +23 -17
- package/dist/esm/wizard/index.js +171 -103
- package/dist/esm/wizard/store/index.js +169 -116
- package/dist/esm/wizard/store/utils.js +13 -6
- package/package.json +30 -16
- package/release.config.js +1 -0
- package/shared/hooks/use-coauthors.js +195 -27
- package/shared/hooks/use-coauthors.test.js +232 -6
- package/shared/scss/_mixins.scss +13 -5
- package/src/accordion/index.js +8 -7
- package/src/action-card/index.js +15 -1
- package/src/badge/index.tsx +3 -1
- package/src/card/core-card.js +95 -18
- package/src/card/index.js +1 -0
- package/src/card/style-core.scss +93 -25
- package/src/card/style.scss +2 -2
- package/src/card-feature/README.md +188 -0
- package/src/card-feature/index.tsx +186 -0
- package/src/card-feature/style.scss +75 -0
- package/src/card-form/README.md +113 -0
- package/src/card-form/index.tsx +128 -0
- package/src/card-form/style.scss +20 -0
- package/src/card-settings-group/index.tsx +28 -3
- package/src/card-sortable-list/index.tsx +27 -4
- package/src/color-picker/index.js +15 -8
- package/src/color-picker/index.test.js +52 -0
- package/src/color-picker/style.scss +11 -13
- package/src/confirm-dialog/README.md +128 -0
- package/src/confirm-dialog/index.tsx +74 -6
- package/src/dataviews/index.tsx +34 -0
- package/src/dataviews/style.scss +9 -0
- package/src/grid/style.scss +6 -1
- package/src/handoff/README.md +93 -0
- package/src/handoff/index.js +46 -8
- package/src/hooks/index.ts +2 -1
- package/src/hooks/use-confirm-dialog.tsx +80 -0
- package/src/hooks/use-unsaved-changes-dialog.tsx +140 -0
- package/src/image-upload/index.js +10 -15
- package/src/image-upload/style.scss +12 -40
- package/src/index.js +7 -1
- package/src/integration-icons/active-campaign.js +14 -0
- package/src/integration-icons/constant-contact.js +22 -0
- package/src/integration-icons/fundraise-up.js +18 -0
- package/src/integration-icons/index.js +6 -0
- package/src/integration-icons/mailchimp.js +10 -0
- package/src/integration-icons/salesforce.js +10 -0
- package/src/integration-icons/wisepops.js +14 -0
- package/src/modal/style.scss +4 -0
- package/src/plugin-installer/index.js +30 -19
- package/src/section-header/index.js +56 -24
- package/src/section-header/style.scss +31 -11
- package/src/select-control/index.js +4 -0
- package/src/utils/editor-toolbar-back-button.tsx +48 -0
- package/src/utils/index.js +6 -0
- package/src/utils/style.scss +8 -0
- package/src/with-wizard/style.scss +4 -54
- package/src/with-wizard-screen/style.scss +41 -3
- package/src/wizard/index.js +90 -53
- package/src/wizard/store/index.js +2 -2
- package/dist/cjs/button-card/index.js +0 -72
- package/dist/cjs/button-card/style.scss +0 -180
- package/dist/esm/button-card/index.js +0 -64
- package/dist/esm/button-card/style.scss +0 -180
- package/src/button-card/index.js +0 -52
- package/src/button-card/style.scss +0 -180
package/src/card/core-card.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* WordPress dependencies
|
|
8
8
|
*/
|
|
9
9
|
import { __ } from '@wordpress/i18n';
|
|
10
|
-
import { Button, Card as CardWrapper, CardHeader, CardFooter, DropdownMenu, MenuItem, ToggleControl } from '@wordpress/components';
|
|
10
|
+
import { Button, Card as CardWrapper, CardHeader, CardFooter, DropdownMenu, MenuGroup, MenuItem, ToggleControl } from '@wordpress/components';
|
|
11
11
|
import { Icon, chevronDown, chevronRight, chevronUp, dragHandle, moreVertical } from '@wordpress/icons';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -28,6 +28,11 @@ const CoreCard = ( {
|
|
|
28
28
|
className,
|
|
29
29
|
footer,
|
|
30
30
|
header,
|
|
31
|
+
headerAction,
|
|
32
|
+
headerStyle,
|
|
33
|
+
childrenStyle,
|
|
34
|
+
footerStyle,
|
|
35
|
+
disabled,
|
|
31
36
|
icon,
|
|
32
37
|
iconBackgroundColor,
|
|
33
38
|
isActive,
|
|
@@ -38,24 +43,30 @@ const CoreCard = ( {
|
|
|
38
43
|
isSmall,
|
|
39
44
|
dragIndex,
|
|
40
45
|
onDragCallback = () => {},
|
|
46
|
+
onToggle = () => {},
|
|
41
47
|
onHeaderClick,
|
|
42
48
|
noBorder,
|
|
43
49
|
noMargin,
|
|
44
50
|
children = null,
|
|
51
|
+
hasGreyHeader,
|
|
52
|
+
hasHeaderBorder = true,
|
|
45
53
|
...otherProps
|
|
46
54
|
} ) => {
|
|
47
55
|
const classes = classNames(
|
|
48
56
|
'newspack-card--core',
|
|
49
57
|
className,
|
|
50
58
|
( buttonsCard || as === 'a' ) && 'newspack-card--core__buttons-card',
|
|
59
|
+
actions?.length > 0 && 'newspack-card--core__header--has-actions',
|
|
51
60
|
isDraggable && 'newspack-card--core__is-draggable',
|
|
52
61
|
isNarrow && 'newspack-card--core__is-narrow',
|
|
53
62
|
isSmall && 'newspack-card--core__is-small',
|
|
54
63
|
icon && 'newspack-card--core__has-icon',
|
|
55
64
|
iconBackgroundColor && 'newspack-card--core__has-icon-background-color',
|
|
56
65
|
isActive && 'newspack-card--core__is-active',
|
|
66
|
+
disabled && 'newspack-card--core__is-disabled',
|
|
57
67
|
children && 'newspack-card--core__has-children',
|
|
58
|
-
noMargin && 'newspack-card--core__no-margin'
|
|
68
|
+
noMargin && 'newspack-card--core__no-margin',
|
|
69
|
+
hasGreyHeader && 'newspack-card--core__has-grey-header'
|
|
59
70
|
);
|
|
60
71
|
let sizeProps = isSmall ? 'small' : otherProps.size;
|
|
61
72
|
if ( buttonsCard || as === 'a' ) {
|
|
@@ -74,9 +85,17 @@ const CoreCard = ( {
|
|
|
74
85
|
{ ( header || icon ) && (
|
|
75
86
|
<CardHeader
|
|
76
87
|
as={ onHeaderClick ? 'button' : undefined }
|
|
77
|
-
className={ classNames(
|
|
88
|
+
className={ classNames(
|
|
89
|
+
'newspack-card--core__header',
|
|
90
|
+
isDraggable && 'newspack-card--core__header--is-draggable',
|
|
91
|
+
! hasHeaderBorder && 'newspack-card--core__header--no-border'
|
|
92
|
+
) }
|
|
93
|
+
style={ headerStyle }
|
|
78
94
|
size={ sizeProps }
|
|
79
|
-
|
|
95
|
+
gap={ 4 }
|
|
96
|
+
onClick={ disabled ? undefined : onHeaderClick }
|
|
97
|
+
disabled={ onHeaderClick && disabled ? true : undefined }
|
|
98
|
+
aria-disabled={ onHeaderClick && disabled ? true : undefined }
|
|
80
99
|
>
|
|
81
100
|
{ isDraggable && (
|
|
82
101
|
<div className="newspack-card--core__header__draggable-controls">
|
|
@@ -106,6 +125,15 @@ const CoreCard = ( {
|
|
|
106
125
|
<Icon icon={ icon } height={ isSmall ? 24 : 48 } width={ isSmall ? 24 : 48 } />
|
|
107
126
|
</div>
|
|
108
127
|
) }
|
|
128
|
+
{ actions?.length > 0 && actionType === 'toggle' && (
|
|
129
|
+
<ToggleControl
|
|
130
|
+
className="newspack-card--core__action"
|
|
131
|
+
label={ otherProps.title }
|
|
132
|
+
hideLabelFromVision
|
|
133
|
+
checked={ isActive }
|
|
134
|
+
onChange={ onToggle }
|
|
135
|
+
/>
|
|
136
|
+
) }
|
|
109
137
|
{ header && <div className="newspack-card--core__header-content">{ header }</div> }
|
|
110
138
|
{ ! actions?.length > 0 && actionType === 'chevron' && (
|
|
111
139
|
<Icon className="newspack-card--core__action" icon={ chevronRight } height={ 24 } width={ 24 } />
|
|
@@ -116,30 +144,79 @@ const CoreCard = ( {
|
|
|
116
144
|
label={ otherProps.title }
|
|
117
145
|
hideLabelFromVision
|
|
118
146
|
checked={ isActive }
|
|
119
|
-
onChange={
|
|
147
|
+
onChange={ onToggle }
|
|
120
148
|
/>
|
|
121
149
|
) }
|
|
122
150
|
{ actions?.length > 0 && (
|
|
123
151
|
<DropdownMenu icon={ moreVertical } label={ __( 'More', 'newspack-plugin' ) }>
|
|
124
152
|
{ () =>
|
|
125
|
-
actions.map( ( action, index ) =>
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
153
|
+
actions.map( ( action, index ) => {
|
|
154
|
+
// Actions can be an array of sub-actions, which are rendered within a MenuGroup.
|
|
155
|
+
if ( Array.isArray( action ) ) {
|
|
156
|
+
return (
|
|
157
|
+
<MenuGroup key={ index }>
|
|
158
|
+
{ action.map( ( subAction, i ) => {
|
|
159
|
+
return (
|
|
160
|
+
<MenuItem
|
|
161
|
+
key={ i }
|
|
162
|
+
icon={ subAction.icon }
|
|
163
|
+
onClick={ subAction.action }
|
|
164
|
+
href={ subAction.href }
|
|
165
|
+
disabled={ subAction.disabled || false }
|
|
166
|
+
isDestructive={ subAction.destructive || false }
|
|
167
|
+
>
|
|
168
|
+
{ subAction.label }
|
|
169
|
+
</MenuItem>
|
|
170
|
+
);
|
|
171
|
+
} ) }
|
|
172
|
+
</MenuGroup>
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
return (
|
|
176
|
+
<MenuItem
|
|
177
|
+
key={ index }
|
|
178
|
+
icon={ action.icon }
|
|
179
|
+
onClick={ action.action }
|
|
180
|
+
href={ action.href }
|
|
181
|
+
disabled={ action.disabled || false }
|
|
182
|
+
isDestructive={ action.destructive || false }
|
|
183
|
+
>
|
|
184
|
+
{ action.label }
|
|
185
|
+
</MenuItem>
|
|
186
|
+
);
|
|
187
|
+
} )
|
|
136
188
|
}
|
|
137
189
|
</DropdownMenu>
|
|
138
190
|
) }
|
|
191
|
+
{ headerAction && (
|
|
192
|
+
<Button
|
|
193
|
+
className="newspack-card--core__header__action"
|
|
194
|
+
icon={ headerAction.icon }
|
|
195
|
+
href={ headerAction.href }
|
|
196
|
+
disabled={ headerAction.disabled || false }
|
|
197
|
+
isDestructive={ headerAction.destructive || false }
|
|
198
|
+
onClick={ headerAction.onClick }
|
|
199
|
+
tone={ headerAction.tone || 'primary' }
|
|
200
|
+
variant={ headerAction.variant || 'secondary' }
|
|
201
|
+
>
|
|
202
|
+
{ headerAction.label }
|
|
203
|
+
</Button>
|
|
204
|
+
) }
|
|
139
205
|
</CardHeader>
|
|
140
206
|
) }
|
|
141
|
-
{ children &&
|
|
142
|
-
|
|
207
|
+
{ children && (
|
|
208
|
+
<div
|
|
209
|
+
className={ classNames( 'newspack-card--core__body', ! hasHeaderBorder && 'newspack-card--core__body--no-header-border' ) }
|
|
210
|
+
style={ childrenStyle }
|
|
211
|
+
>
|
|
212
|
+
{ children }
|
|
213
|
+
</div>
|
|
214
|
+
) }
|
|
215
|
+
{ footer && (
|
|
216
|
+
<CardFooter size={ sizeProps } style={ footerStyle }>
|
|
217
|
+
{ footer }
|
|
218
|
+
</CardFooter>
|
|
219
|
+
) }
|
|
143
220
|
</CardWrapper>
|
|
144
221
|
);
|
|
145
222
|
};
|
package/src/card/index.js
CHANGED
package/src/card/style-core.scss
CHANGED
|
@@ -3,26 +3,27 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
@use "~@wordpress/base-styles/colors" as wp-colors;
|
|
6
|
+
@use "~@wordpress/base-styles/variables" as wp-vars;
|
|
6
7
|
@use "../../../colors/colors.module" as colors;
|
|
7
8
|
|
|
8
9
|
.newspack-card--core,
|
|
9
10
|
.newspack-wizard .newspack-card--core {
|
|
10
|
-
background: white;
|
|
11
|
+
background: wp-colors.$white;
|
|
11
12
|
position: relative;
|
|
12
13
|
transition: background-color 125ms ease-in-out, box-shadow 125ms ease-in-out, color 125ms ease-in-out;
|
|
13
14
|
svg {
|
|
14
15
|
transition: fill 125ms ease-in-out;
|
|
15
16
|
}
|
|
16
17
|
&__icon {
|
|
17
|
-
border-radius:
|
|
18
|
+
border-radius: wp-vars.$radius-round;
|
|
18
19
|
display: grid;
|
|
19
|
-
height:
|
|
20
|
+
height: wp-vars.$grid-unit-60;
|
|
20
21
|
place-items: center;
|
|
21
|
-
width:
|
|
22
|
+
width: wp-vars.$grid-unit-60;
|
|
22
23
|
svg {
|
|
23
24
|
fill: var(--wp-admin-theme-color);
|
|
24
|
-
height:
|
|
25
|
-
width:
|
|
25
|
+
height: wp-vars.$grid-unit-50;
|
|
26
|
+
width: wp-vars.$grid-unit-50;
|
|
26
27
|
}
|
|
27
28
|
.newspack-card--core__has-icon-background-color & {
|
|
28
29
|
background: var(--wp-admin-theme-color-lighter-10);
|
|
@@ -35,24 +36,37 @@
|
|
|
35
36
|
h4,
|
|
36
37
|
h5,
|
|
37
38
|
h6 {
|
|
38
|
-
font-size:
|
|
39
|
-
font-weight: 500;
|
|
39
|
+
font-size: wp-vars.$font-size-large;
|
|
40
40
|
}
|
|
41
|
-
.newspack-card--
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
.newspack-card--core {
|
|
42
|
+
&__header-content {
|
|
43
|
+
* {
|
|
44
|
+
line-height: wp-vars.$font-line-height-small;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
&__icon {
|
|
48
|
+
height: wp-vars.$grid-unit-50;
|
|
49
|
+
width: wp-vars.$grid-unit-50;
|
|
50
|
+
svg {
|
|
51
|
+
height: wp-vars.$grid-unit-30;
|
|
52
|
+
width: wp-vars.$grid-unit-30;
|
|
53
|
+
}
|
|
47
54
|
}
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
&__no-margin .components-card__body {
|
|
51
58
|
padding: 0 !important;
|
|
52
59
|
}
|
|
60
|
+
&__is-disabled {
|
|
61
|
+
cursor: not-allowed;
|
|
62
|
+
opacity: 0.5;
|
|
63
|
+
.newspack-card--core__header {
|
|
64
|
+
pointer-events: none;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
53
67
|
&__header {
|
|
54
68
|
color: wp-colors.$gray-700;
|
|
55
|
-
|
|
69
|
+
flex-wrap: wrap;
|
|
56
70
|
position: relative;
|
|
57
71
|
.newspack-card--core__action {
|
|
58
72
|
margin: 0;
|
|
@@ -68,22 +82,26 @@
|
|
|
68
82
|
word-wrap: normal !important;
|
|
69
83
|
}
|
|
70
84
|
}
|
|
71
|
-
.components-dropdown-menu {
|
|
85
|
+
> .components-dropdown-menu {
|
|
72
86
|
aspect-ratio: 1;
|
|
73
87
|
border-left: 1px solid wp-colors.$gray-200;
|
|
74
88
|
display: grid;
|
|
75
89
|
height: 100%;
|
|
90
|
+
max-width: 50px;
|
|
76
91
|
padding: 4px;
|
|
77
92
|
place-items: center;
|
|
78
93
|
position: absolute;
|
|
79
94
|
right: 0;
|
|
80
95
|
top: 0;
|
|
81
96
|
}
|
|
97
|
+
&__action {
|
|
98
|
+
background-color: wp-colors.$white;
|
|
99
|
+
flex: 1 100%;
|
|
100
|
+
justify-content: center !important;
|
|
101
|
+
}
|
|
82
102
|
}
|
|
83
103
|
&__header--is-draggable {
|
|
84
|
-
|
|
85
|
-
padding-left: 65px;
|
|
86
|
-
}
|
|
104
|
+
padding-left: 80px !important;
|
|
87
105
|
.newspack-card--core__header__draggable-controls {
|
|
88
106
|
align-items: center;
|
|
89
107
|
border-right: 1px solid wp-colors.$gray-200;
|
|
@@ -110,6 +128,21 @@
|
|
|
110
128
|
}
|
|
111
129
|
}
|
|
112
130
|
}
|
|
131
|
+
// Two classes beat the single-class .components-card__header border-bottom
|
|
132
|
+
// rule from WP Core without needing !important.
|
|
133
|
+
&__header.newspack-card--core__header--no-border {
|
|
134
|
+
border-bottom: none;
|
|
135
|
+
}
|
|
136
|
+
&__body.newspack-card--core__body--no-header-border {
|
|
137
|
+
> div:not(.components-card__body):not(.components-card__media):not(.components-card__divider) {
|
|
138
|
+
padding-top: 0;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
&__header--has-actions {
|
|
142
|
+
.newspack-card--core__header {
|
|
143
|
+
padding-right: 70px;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
113
146
|
button.newspack-card--core__header {
|
|
114
147
|
appearance: none;
|
|
115
148
|
background-color: white;
|
|
@@ -140,18 +173,25 @@
|
|
|
140
173
|
h6 {
|
|
141
174
|
align-items: center;
|
|
142
175
|
color: wp-colors.$gray-900;
|
|
143
|
-
font-weight:
|
|
176
|
+
font-weight: 600;
|
|
144
177
|
display: flex;
|
|
145
178
|
gap: 8px;
|
|
179
|
+
a {
|
|
180
|
+
color: inherit;
|
|
181
|
+
text-decoration: none;
|
|
182
|
+
&:hover {
|
|
183
|
+
text-decoration: underline;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
146
186
|
.newspack-badge {
|
|
147
187
|
font-weight: 400;
|
|
148
188
|
}
|
|
149
189
|
}
|
|
150
190
|
}
|
|
151
|
-
&__is-active {
|
|
191
|
+
&__is-active:not(.newspack-card--core__is-draggable) {
|
|
152
192
|
border-color: var(--wp-admin-theme-color);
|
|
153
193
|
box-shadow: var(--wp-admin-theme-color) 0 0 0 1px;
|
|
154
|
-
|
|
194
|
+
.newspack-card--core__header {
|
|
155
195
|
background-color: rgba( var(--wp-admin-theme-color--rgb), 0.04 );
|
|
156
196
|
color: var(--wp-admin-theme-color);
|
|
157
197
|
h1,
|
|
@@ -168,7 +208,7 @@
|
|
|
168
208
|
}
|
|
169
209
|
|
|
170
210
|
&.newspack-card--core__has-children {
|
|
171
|
-
|
|
211
|
+
.newspack-card--core__header {
|
|
172
212
|
border-bottom-left-radius: 0;
|
|
173
213
|
border-bottom-right-radius: 0;
|
|
174
214
|
}
|
|
@@ -203,14 +243,39 @@
|
|
|
203
243
|
}
|
|
204
244
|
}
|
|
205
245
|
}
|
|
246
|
+
&.is-destructive {
|
|
247
|
+
.newspack-card--core__header {
|
|
248
|
+
h1,
|
|
249
|
+
h2,
|
|
250
|
+
h3,
|
|
251
|
+
h4,
|
|
252
|
+
h5,
|
|
253
|
+
h6 {
|
|
254
|
+
color: wp-colors.$alert-red;
|
|
255
|
+
}
|
|
256
|
+
&:hover,
|
|
257
|
+
&:focus {
|
|
258
|
+
background-color: wp-colors.$gray-100;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
.newspack-card--core__action,
|
|
262
|
+
.newspack-card--core__action svg {
|
|
263
|
+
fill: wp-colors.$alert-red;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
206
266
|
hr.components-card__divider {
|
|
207
267
|
margin: 0;
|
|
208
268
|
}
|
|
209
269
|
&__is-narrow {
|
|
210
270
|
margin-left: auto;
|
|
211
271
|
margin-right: auto;
|
|
212
|
-
@media screen and ( min-width:
|
|
213
|
-
max-width:
|
|
272
|
+
@media screen and ( min-width: 615px ) {
|
|
273
|
+
max-width: 583px;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
&__has-grey-header {
|
|
277
|
+
.newspack-card--core__header {
|
|
278
|
+
background-color: rgba(black, 0.025);
|
|
214
279
|
}
|
|
215
280
|
}
|
|
216
281
|
&__body {
|
|
@@ -223,5 +288,8 @@
|
|
|
223
288
|
padding: 0;
|
|
224
289
|
}
|
|
225
290
|
}
|
|
291
|
+
> .components-card__media {
|
|
292
|
+
border-radius: 0 !important;
|
|
293
|
+
}
|
|
226
294
|
}
|
|
227
295
|
}
|
package/src/card/style.scss
CHANGED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# CardFeature
|
|
2
|
+
|
|
3
|
+
A card component for presenting a named feature or setting with a predictable, state-driven interaction model. It handles the primary button, an optional "More" dropdown, and a badge automatically based on the `enabled` and `requirements` props.
|
|
4
|
+
|
|
5
|
+
## Layout rules
|
|
6
|
+
|
|
7
|
+
- **Maximum 2 cards per row.** Use `<Grid columns={ 2 }>` — never 3 or more. Cards are designed to be read, not scanned, and 3+ columns makes them too narrow for the content.
|
|
8
|
+
- The icon is always displayed on the **right-hand side**, aligned to the top of the content.
|
|
9
|
+
|
|
10
|
+
## States
|
|
11
|
+
|
|
12
|
+
| State | Condition | Button | Dropdown | Badge |
|
|
13
|
+
|---|---|---|---|---|
|
|
14
|
+
| **Unmet requirements** | `requirements` is set | "Enable" — disabled (clickable if `requirementsActionable`) | Hidden | Error badge with `requirements` text |
|
|
15
|
+
| **Disabled** | `!enabled`, no requirements | "Enable" | Hidden | None |
|
|
16
|
+
| **Enabled** | `enabled`, no requirements | "Configure" | Shown if `moreControls` provided | Success badge ("Enabled") |
|
|
17
|
+
|
|
18
|
+
The card content (title + description) is visually muted (gray text, lighter border) when `requirements` is set.
|
|
19
|
+
|
|
20
|
+
## Basic usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { __ } from '@wordpress/i18n';
|
|
24
|
+
|
|
25
|
+
<CardFeature
|
|
26
|
+
title={ __( 'Metered countdown', 'newspack-plugin' ) }
|
|
27
|
+
description={ __( 'Show a countdown banner letting readers know how many free views they have left.', 'newspack-plugin' ) }
|
|
28
|
+
enabled={ isEnabled }
|
|
29
|
+
onEnable={ () => setEnabled( true ) }
|
|
30
|
+
onConfigure={ () => history.push( '/settings/countdown' ) }
|
|
31
|
+
moreControls={ [
|
|
32
|
+
{ title: __( 'Disable', 'newspack-plugin' ), onClick: () => setEnabled( false ) },
|
|
33
|
+
] }
|
|
34
|
+
/>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## With unmet requirements
|
|
38
|
+
|
|
39
|
+
When `requirements` is set the button is disabled and an error badge displays the string. The title and description are visually muted.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { __ } from '@wordpress/i18n';
|
|
43
|
+
|
|
44
|
+
<CardFeature
|
|
45
|
+
title={ __( 'Metered countdown', 'newspack-plugin' ) }
|
|
46
|
+
description={ __( 'Show a countdown banner letting readers know how many free views they have left.', 'newspack-plugin' ) }
|
|
47
|
+
enabled={ isEnabled }
|
|
48
|
+
requirements={ __( 'Requires metering', 'newspack-plugin' ) }
|
|
49
|
+
onEnable={ () => setEnabled( true ) }
|
|
50
|
+
onConfigure={ () => history.push( '/settings/countdown' ) }
|
|
51
|
+
moreControls={ [
|
|
52
|
+
{ title: __( 'Disable', 'newspack-plugin' ), onClick: () => setEnabled( false ) },
|
|
53
|
+
] }
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## With a custom icon
|
|
58
|
+
|
|
59
|
+
The `icon` prop accepts an object, not a bare node. Pass `node` for the icon element, `fill` to control the SVG colour (applied via `currentColor`), `backgroundColor` for a container background, and `radius` for the corner treatment.
|
|
60
|
+
|
|
61
|
+
The icon container is always **40 × 40 px** with the SVG at **24 × 24 px**. `radius` only applies when `backgroundColor` is set.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
import { __ } from '@wordpress/i18n';
|
|
65
|
+
import { Icon, starFilled } from '@wordpress/icons';
|
|
66
|
+
|
|
67
|
+
// Icon with fill only
|
|
68
|
+
<CardFeature
|
|
69
|
+
title={ __( 'Content gifting', 'newspack-plugin' ) }
|
|
70
|
+
description={ __( 'Let subscribers share gated articles with non-subscribers.', 'newspack-plugin' ) }
|
|
71
|
+
icon={ { node: <Icon icon={ starFilled } />, fill: '#003da5' } }
|
|
72
|
+
enabled={ isEnabled }
|
|
73
|
+
onEnable={ handleEnable }
|
|
74
|
+
onConfigure={ handleConfigure }
|
|
75
|
+
moreControls={ [ { title: __( 'Disable', 'newspack-plugin' ), onClick: handleDisable } ] }
|
|
76
|
+
/>
|
|
77
|
+
|
|
78
|
+
// Icon with circular background
|
|
79
|
+
<CardFeature
|
|
80
|
+
title={ __( 'Content gifting', 'newspack-plugin' ) }
|
|
81
|
+
description={ __( 'Let subscribers share gated articles with non-subscribers.', 'newspack-plugin' ) }
|
|
82
|
+
icon={ { node: <Icon icon={ starFilled } />, fill: '#003da5', backgroundColor: '#dfe7f4', radius: 'full' } }
|
|
83
|
+
enabled={ isEnabled }
|
|
84
|
+
onEnable={ handleEnable }
|
|
85
|
+
onConfigure={ handleConfigure }
|
|
86
|
+
moreControls={ [ { title: __( 'Disable', 'newspack-plugin' ), onClick: handleDisable } ] }
|
|
87
|
+
/>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## With custom button labels
|
|
91
|
+
|
|
92
|
+
Override `enableLabel` and `configureLabel` to match the context of the feature.
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
import { __ } from '@wordpress/i18n';
|
|
96
|
+
|
|
97
|
+
<CardFeature
|
|
98
|
+
title={ __( 'Apple News', 'newspack-plugin' ) }
|
|
99
|
+
description={ __( 'Automatically publish articles to Apple News.', 'newspack-plugin' ) }
|
|
100
|
+
enabled={ isEnabled }
|
|
101
|
+
enableLabel={ __( 'Connect', 'newspack-plugin' ) }
|
|
102
|
+
configureLabel={ __( 'Manage connection', 'newspack-plugin' ) }
|
|
103
|
+
onEnable={ handleConnect }
|
|
104
|
+
onConfigure={ () => history.push( '/settings/apple-news' ) }
|
|
105
|
+
moreControls={ [ { title: __( 'Disconnect', 'newspack-plugin' ), onClick: handleDisconnect } ] }
|
|
106
|
+
/>
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## With a custom badge
|
|
110
|
+
|
|
111
|
+
Override `badgeText` and `badgeLevel` to change the badge shown when the feature is enabled. Available levels: `default`, `info`, `success`, `warning`, `error`.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import { __ } from '@wordpress/i18n';
|
|
115
|
+
|
|
116
|
+
<CardFeature
|
|
117
|
+
title={ __( 'Stripe', 'newspack-plugin' ) }
|
|
118
|
+
description={ __( 'Accept payments via Stripe.', 'newspack-plugin' ) }
|
|
119
|
+
enabled={ isEnabled }
|
|
120
|
+
badgeText={ __( 'Live mode', 'newspack-plugin' ) }
|
|
121
|
+
badgeLevel="info"
|
|
122
|
+
onEnable={ handleEnable }
|
|
123
|
+
onConfigure={ () => history.push( '/settings/stripe' ) }
|
|
124
|
+
moreControls={ [ { title: __( 'Disable', 'newspack-plugin' ), onClick: handleDisable } ] }
|
|
125
|
+
/>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## With multiple "More" controls
|
|
129
|
+
|
|
130
|
+
`moreControls` accepts any number of items, each with a `title`, `onClick`, and an optional `icon`.
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import { __ } from '@wordpress/i18n';
|
|
134
|
+
|
|
135
|
+
<CardFeature
|
|
136
|
+
title={ __( 'Newsletters', 'newspack-plugin' ) }
|
|
137
|
+
description={ __( 'Send newsletters directly from the WordPress editor.', 'newspack-plugin' ) }
|
|
138
|
+
enabled={ isEnabled }
|
|
139
|
+
onEnable={ handleEnable }
|
|
140
|
+
onConfigure={ () => history.push( '/settings/newsletters' ) }
|
|
141
|
+
moreControls={ [
|
|
142
|
+
{ title: __( 'Edit', 'newspack-plugin' ), onClick: handleEdit },
|
|
143
|
+
{ title: __( 'Preview', 'newspack-plugin' ), onClick: handlePreview },
|
|
144
|
+
{ title: __( 'Disable', 'newspack-plugin' ), onClick: handleDisable },
|
|
145
|
+
] }
|
|
146
|
+
/>
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Props
|
|
150
|
+
|
|
151
|
+
| Prop | Type | Default | Description |
|
|
152
|
+
|---|---|---|---|
|
|
153
|
+
| `title` | `string` | — | Card heading (**required**) |
|
|
154
|
+
| `description` | `string` | — | Supporting text below the title |
|
|
155
|
+
| `icon` | `CardFeatureIcon` | — | Icon displayed on the right. See `CardFeatureIcon` below. |
|
|
156
|
+
| `enabled` | `boolean` | `false` | Whether the feature is currently enabled |
|
|
157
|
+
| `requirements` | `string` | — | When set, enters the unmet-requirements state; value is used as the error badge text |
|
|
158
|
+
| `requirementsActionable` | `boolean` | `false` | When `requirements` is set, keep the primary button clickable so it can remediate the unmet requirement |
|
|
159
|
+
| `enableLabel` | `string` | `"Enable"` | Primary button label when not enabled |
|
|
160
|
+
| `configureLabel` | `string` | `"Configure"` | Primary button label when enabled |
|
|
161
|
+
| `onEnable` | `() => void` | — | Called when the primary button is clicked and the feature is not enabled |
|
|
162
|
+
| `onConfigure` | `() => void` | — | Called when the primary button is clicked and the feature is enabled |
|
|
163
|
+
| `moreControls` | `MoreControl[]` | — | Items for the "More" dropdown, shown only when enabled |
|
|
164
|
+
| `badgeText` | `string` | `"Enabled"` | Badge text shown when enabled |
|
|
165
|
+
| `badgeLevel` | `BadgeLevel` | `"success"` | Badge level shown when enabled |
|
|
166
|
+
| `className` | `string` | — | Additional class name applied to the card element |
|
|
167
|
+
|
|
168
|
+
### `CardFeatureIcon`
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
type CardFeatureIcon = {
|
|
172
|
+
node: React.ReactNode; // The icon element to render
|
|
173
|
+
fill?: string; // SVG fill colour (applied via currentColor)
|
|
174
|
+
backgroundColor?: string; // Background colour of the 40×40 container
|
|
175
|
+
radius?: 'small' | 'full'; // 'small' = 2px ($radius-small), 'full' = 50% ($radius-round)
|
|
176
|
+
// Only applied when backgroundColor is set.
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### `MoreControl`
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
type MoreControl = {
|
|
184
|
+
title: string;
|
|
185
|
+
onClick: () => void;
|
|
186
|
+
icon?: React.ReactNode;
|
|
187
|
+
};
|
|
188
|
+
```
|