@automattic/newspack-blocks 1.67.0 → 1.68.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.
- package/.cache/babel/078314f1ffd302d32bbe1124c797c4a8.json.gz +0 -0
- package/.cache/babel/08bd669298cd26a7d3a62aadcf637516.json.gz +0 -0
- package/.cache/babel/0988afa42fd3fe14da7ae43c9d02661e.json.gz +0 -0
- package/.cache/babel/0d164bb53cdb3442a8c8ab37dde2e4ce.json.gz +0 -0
- package/.cache/babel/0f96392a3b96da0b4dce7a77edef76ca.json.gz +0 -0
- package/.cache/babel/2dc630cecd79488c7912540ac3a1ae93.json.gz +0 -0
- package/.cache/babel/3807c3306deecdbdb91968cb3c978235.json.gz +0 -0
- package/.cache/babel/45308b31d062a1fb08079849840aaa43.json.gz +0 -0
- package/.cache/babel/48df6fe3b45d872e1ded6f33a70e3176.json.gz +0 -0
- package/.cache/babel/58350a62e3ef63157722789bf187a8d1.json.gz +0 -0
- package/.cache/babel/5ac50f37a9913d9f63c8751f5c415ba4.json.gz +0 -0
- package/.cache/babel/6170ac021bca94b65aaf9d91313c47a9.json.gz +0 -0
- package/.cache/babel/66c747a8bdec1ed403f703e47256fa03.json.gz +0 -0
- package/.cache/babel/695780d53e2d31de09fc42456ad05cff.json.gz +0 -0
- package/.cache/babel/6bc92299b6332d48bcc944e155ce08cd.json.gz +0 -0
- package/.cache/babel/900ca42963bd0a74c1498a6d1212d82f.json.gz +0 -0
- package/.cache/babel/91e706536d45a88f098e9394344dbeb9.json.gz +0 -0
- package/.cache/babel/ab39cbb804689d063293f37fa4485487.json.gz +0 -0
- package/.cache/babel/c0e75e9017dcf69507da774f93b23422.json.gz +0 -0
- package/.cache/babel/c917c2bc027ccb946305c9305b05755e.json.gz +0 -0
- package/.cache/babel/cf24b1c63d0cf0e037eb598706a79f88.json.gz +0 -0
- package/.cache/babel/e452902bef688c901938b578c6834c50.json.gz +0 -0
- package/.cache/babel/e499e66d1cc40fb9b6c4238bf3dd2e6a.json.gz +0 -0
- package/.cache/babel/f7fd26614549b5cbb31416d632c38ccd.json.gz +0 -0
- package/.cache/babel/fa8281f6c9d0ec08fd8106dcfff2b6ba.json.gz +0 -0
- package/CHANGELOG.md +42 -0
- package/block-list.json +10 -1
- package/composer.lock +7 -7
- package/dist/carousel/view.asset.php +1 -1
- package/dist/carousel/view.js +1 -1
- package/dist/{donateCheckoutBlock.asset.php → checkout-button/view.asset.php} +1 -1
- package/dist/checkout-button/view.css +1 -0
- package/dist/checkout-button/view.rtl.css +1 -0
- package/dist/donate/view.asset.php +1 -1
- package/dist/donate/view.css +1 -1
- package/dist/donate/view.rtl.css +1 -1
- package/dist/editor.asset.php +1 -1
- package/dist/editor.css +1 -1
- package/dist/editor.js +3 -3
- package/dist/editor.rtl.css +1 -1
- package/dist/{donateCheckoutModal.asset.php → modal.asset.php} +1 -1
- package/dist/modal.css +1 -0
- package/dist/modal.js +1 -0
- package/dist/modal.rtl.css +1 -0
- package/dist/modalCheckout.asset.php +1 -0
- package/dist/modalCheckout.js +1 -0
- package/includes/class-modal-checkout.php +383 -0
- package/includes/class-newspack-blocks.php +30 -6
- package/newspack-blocks.php +3 -2
- package/package.json +3 -3
- package/src/blocks/carousel/edit.js +21 -0
- package/src/blocks/carousel/index.js +3 -0
- package/src/blocks/carousel/view.php +7 -0
- package/src/blocks/checkout-button/block.json +79 -0
- package/src/blocks/checkout-button/edit.js +247 -0
- package/src/blocks/checkout-button/edit.scss +40 -0
- package/src/blocks/checkout-button/editor.js +23 -0
- package/src/blocks/checkout-button/index.js +27 -0
- package/src/blocks/checkout-button/save.js +64 -0
- package/src/blocks/{donate/checkout-modal/index.js → checkout-button/view.js} +1 -1
- package/src/blocks/checkout-button/view.php +35 -0
- package/src/blocks/checkout-button/view.scss +18 -0
- package/src/blocks/donate/frontend/class-newspack-blocks-donate-renderer.php +1 -233
- package/src/blocks/donate/styles/view.scss +0 -95
- package/src/blocks/homepage-articles/block.json +5 -0
- package/src/blocks/homepage-articles/edit.js +18 -0
- package/src/blocks/homepage-articles/utils.ts +4 -0
- package/src/components/query-controls.js +60 -0
- package/src/{blocks/donate/checkout-modal/view.scss → modal-checkout/checkout.scss} +1 -1
- package/src/modal-checkout/index.js +4 -0
- package/src/{blocks/donate/checkout-modal/block.js → modal-checkout/modal.js} +14 -11
- package/src/modal-checkout/modal.scss +97 -0
- package/src/{blocks/donate → modal-checkout}/templates/checkout-form.php +3 -3
- package/src/types/index.d.ts +1 -0
- package/vendor/autoload.php +1 -1
- package/vendor/composer/autoload_real.php +4 -4
- package/vendor/composer/autoload_static.php +2 -2
- package/vendor/composer/installed.php +2 -2
- package/webpack.config.js +2 -2
- package/.cache/babel/1d8b42985da54f10a9bfd0a9f87b5844.json.gz +0 -0
- package/.cache/babel/37bd7f90c2e7ea1e10bf840775d1b262.json.gz +0 -0
- package/.cache/babel/3a66da0fe7ab175effa6a338812e46cb.json.gz +0 -0
- package/.cache/babel/4ba56fc2684f5bebdd2c8c488ea03683.json.gz +0 -0
- package/.cache/babel/60ac312fdf07fb7730b1a8a9c1b5bd5a.json.gz +0 -0
- package/.cache/babel/61d00fc8add441f0b915e3af4b518ead.json.gz +0 -0
- package/.cache/babel/646a7267e14986e70c74dc9c32ca6a14.json.gz +0 -0
- package/.cache/babel/7464c382b8a939e4e43f9349d76843a8.json.gz +0 -0
- package/.cache/babel/917cc52662d270e7c529afbf210a2703.json.gz +0 -0
- package/.cache/babel/a1dde270d38efa30dfbbfe2b97be9e51.json.gz +0 -0
- package/.cache/babel/a5447d9807699029636883e96c6aa4c6.json.gz +0 -0
- package/.cache/babel/a7575c7f77cb736dbfe8a4d01910cc79.json.gz +0 -0
- package/.cache/babel/b13e3fd47c6307f8c1f8786edc053ed9.json.gz +0 -0
- package/.cache/babel/b38122e026094b152ef69677468e4415.json.gz +0 -0
- package/.cache/babel/bb3ca1de54603d2730484164ed55902b.json.gz +0 -0
- package/.cache/babel/c762aee66625f48b1de4e3b329d8c9fe.json.gz +0 -0
- package/.cache/babel/c9d601b83fd7c6412dd9ac187c06d7c1.json.gz +0 -0
- package/.cache/babel/fa5e94ee19268ccad7790a312d6fca4e.json.gz +0 -0
- package/.cache/babel/fe8f3849250ae54c53096ec8db55a8d6.json.gz +0 -0
- package/.cache/babel/fe99fe0bebf3e9d74bb240487620bdd4.json.gz +0 -0
- package/dist/donateCheckoutBlock.js +0 -1
- /package/dist/{donateCheckoutModal.js → checkout-button/view.js} +0 -0
- /package/dist/{donateCheckoutModal.css → modalCheckout.css} +0 -0
- /package/dist/{donateCheckoutModal.rtl.css → modalCheckout.rtl.css} +0 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://schemas.wp.org/trunk/block.json",
|
|
3
|
+
"apiVersion": 2,
|
|
4
|
+
"name": "newspack-blocks/checkout-button",
|
|
5
|
+
"title": "Checkout Button",
|
|
6
|
+
"category": "newspack",
|
|
7
|
+
"description": "Modal checkout button for WooCommerce products.",
|
|
8
|
+
"keywords": [ "woocommerce", "product", "checkout", "button" ],
|
|
9
|
+
"textdomain": "newspack-blocks",
|
|
10
|
+
"attributes": {
|
|
11
|
+
"product": {
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
"price": {
|
|
15
|
+
"type": "string"
|
|
16
|
+
},
|
|
17
|
+
"text": {
|
|
18
|
+
"type": "string"
|
|
19
|
+
},
|
|
20
|
+
"placeholder": {
|
|
21
|
+
"type": "string"
|
|
22
|
+
},
|
|
23
|
+
"backgroundColor": {
|
|
24
|
+
"type": "string"
|
|
25
|
+
},
|
|
26
|
+
"textColor": {
|
|
27
|
+
"type": "string"
|
|
28
|
+
},
|
|
29
|
+
"gradient": {
|
|
30
|
+
"type": "string"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"supports": {
|
|
34
|
+
"anchor": true,
|
|
35
|
+
"align": [ "center", "wide" ],
|
|
36
|
+
"color": {
|
|
37
|
+
"__experimentalSkipSerialization": true,
|
|
38
|
+
"gradients": true,
|
|
39
|
+
"__experimentalDefaultControls": {
|
|
40
|
+
"background": true,
|
|
41
|
+
"text": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"typography": {
|
|
45
|
+
"fontSize": true,
|
|
46
|
+
"lineHeight": true,
|
|
47
|
+
"__experimentalFontFamily": true,
|
|
48
|
+
"__experimentalFontWeight": true,
|
|
49
|
+
"__experimentalFontStyle": true,
|
|
50
|
+
"__experimentalTextTransform": true,
|
|
51
|
+
"__experimentalTextDecoration": true,
|
|
52
|
+
"__experimentalLetterSpacing": true,
|
|
53
|
+
"__experimentalDefaultControls": {
|
|
54
|
+
"fontSize": true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"shadow": true,
|
|
58
|
+
"spacing": {
|
|
59
|
+
"__experimentalSkipSerialization": true,
|
|
60
|
+
"padding": [ "horizontal", "vertical" ],
|
|
61
|
+
"__experimentalDefaultControls": {
|
|
62
|
+
"padding": true
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"__experimentalBorder": {
|
|
66
|
+
"radius": true,
|
|
67
|
+
"__experimentalSkipSerialization": true,
|
|
68
|
+
"__experimentalDefaultControls": {
|
|
69
|
+
"radius": true
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"styles": [
|
|
74
|
+
{ "name": "fill", "label": "Fill", "isDefault": true },
|
|
75
|
+
{ "name": "outline", "label": "Outline" }
|
|
76
|
+
],
|
|
77
|
+
"editorStyle": "newspack-checkout-button-editor",
|
|
78
|
+
"style": "newspack-checkout-block-button"
|
|
79
|
+
}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/* eslint-disable @wordpress/no-unsafe-wp-apis */
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import classnames from 'classnames';
|
|
6
|
+
import { debounce, invert } from 'lodash';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* WordPress dependencies
|
|
10
|
+
*/
|
|
11
|
+
import { __ } from '@wordpress/i18n';
|
|
12
|
+
import {
|
|
13
|
+
InspectorControls,
|
|
14
|
+
RichText,
|
|
15
|
+
useBlockProps,
|
|
16
|
+
__experimentalUseBorderProps as useBorderProps,
|
|
17
|
+
__experimentalUseColorProps as useColorProps,
|
|
18
|
+
__experimentalGetSpacingClassesAndStyles as useSpacingProps,
|
|
19
|
+
} from '@wordpress/block-editor';
|
|
20
|
+
import {
|
|
21
|
+
PanelBody,
|
|
22
|
+
BaseControl,
|
|
23
|
+
TextControl,
|
|
24
|
+
FormTokenField,
|
|
25
|
+
Button,
|
|
26
|
+
Spinner,
|
|
27
|
+
} from '@wordpress/components';
|
|
28
|
+
import { useState, useEffect } from '@wordpress/element';
|
|
29
|
+
import apiFetch from '@wordpress/api-fetch';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Internal dependencies
|
|
33
|
+
*/
|
|
34
|
+
import './edit.scss';
|
|
35
|
+
|
|
36
|
+
function ProductControl( props ) {
|
|
37
|
+
const [ inFlight, setInFlight ] = useState( false );
|
|
38
|
+
const [ suggestions, setSuggestions ] = useState( {} );
|
|
39
|
+
const [ selected, setSelected ] = useState( false );
|
|
40
|
+
const [ isChanging, setIsChanging ] = useState( false );
|
|
41
|
+
function fetchSuggestions( search ) {
|
|
42
|
+
setInFlight( true );
|
|
43
|
+
return apiFetch( {
|
|
44
|
+
path: `/wc/v2/products?search=${ encodeURIComponent( search ) }`,
|
|
45
|
+
} )
|
|
46
|
+
.then( products => {
|
|
47
|
+
const _suggestions = {};
|
|
48
|
+
products.forEach( product => {
|
|
49
|
+
_suggestions[ product.id ] = `${ product.id }: ${ product.name }`;
|
|
50
|
+
} );
|
|
51
|
+
setSuggestions( _suggestions );
|
|
52
|
+
} )
|
|
53
|
+
.finally( () => setInFlight( false ) );
|
|
54
|
+
}
|
|
55
|
+
function fetchSaved() {
|
|
56
|
+
setInFlight( true );
|
|
57
|
+
return apiFetch( {
|
|
58
|
+
path: `/wc/v2/products/${ props.value }`,
|
|
59
|
+
} )
|
|
60
|
+
.then( product => {
|
|
61
|
+
setSuggestions( { [ product.id ]: `${ product.id }: ${ product.name }` } );
|
|
62
|
+
setSelected( product );
|
|
63
|
+
props.onProduct( product );
|
|
64
|
+
} )
|
|
65
|
+
.finally( () => setInFlight( false ) );
|
|
66
|
+
}
|
|
67
|
+
useEffect( () => {
|
|
68
|
+
setIsChanging( false );
|
|
69
|
+
if ( props.value ) {
|
|
70
|
+
fetchSaved();
|
|
71
|
+
} else {
|
|
72
|
+
setSelected( false );
|
|
73
|
+
}
|
|
74
|
+
}, [ props.value ] );
|
|
75
|
+
function onChange( tokens ) {
|
|
76
|
+
const productName = tokens[ 0 ];
|
|
77
|
+
const productId = invert( suggestions )[ productName ];
|
|
78
|
+
setIsChanging( false );
|
|
79
|
+
props.onChange( productId );
|
|
80
|
+
}
|
|
81
|
+
const debouncedFetchProductSuggestions = debounce( fetchSuggestions, 200 );
|
|
82
|
+
const handleInputChange = value => {
|
|
83
|
+
if ( value.length > 2 ) {
|
|
84
|
+
setInFlight( true );
|
|
85
|
+
debouncedFetchProductSuggestions( value );
|
|
86
|
+
} else {
|
|
87
|
+
setInFlight( false );
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
if ( props.value && ! selected && inFlight ) {
|
|
91
|
+
return <Spinner />;
|
|
92
|
+
}
|
|
93
|
+
return (
|
|
94
|
+
<div className="newspack-checkout-button__product-field">
|
|
95
|
+
{ selected && ! isChanging ? (
|
|
96
|
+
<>
|
|
97
|
+
<BaseControl
|
|
98
|
+
className="newspack-checkout-button__product-field__selected"
|
|
99
|
+
help={ __( 'Click to change the selected product', 'newspack-blocks' ) }
|
|
100
|
+
>
|
|
101
|
+
<Button
|
|
102
|
+
isSecondary
|
|
103
|
+
onClick={ () => setIsChanging( true ) }
|
|
104
|
+
aria-label={ __( 'Change the selected product', 'newspack-blocks' ) }
|
|
105
|
+
>
|
|
106
|
+
{ selected.name }
|
|
107
|
+
</Button>
|
|
108
|
+
</BaseControl>
|
|
109
|
+
</>
|
|
110
|
+
) : (
|
|
111
|
+
<>
|
|
112
|
+
<div className="newspack-checkout-button__product-field__tokenfield">
|
|
113
|
+
<FormTokenField
|
|
114
|
+
placeholder={
|
|
115
|
+
props.placeholder || __( 'Type to search for a product…', 'newspack-blocks' )
|
|
116
|
+
}
|
|
117
|
+
label={ __( 'Select a product', 'newspack-blocks' ) }
|
|
118
|
+
maxLength={ 1 }
|
|
119
|
+
onChange={ onChange }
|
|
120
|
+
onInputChange={ handleInputChange }
|
|
121
|
+
suggestions={ Object.values( suggestions ) }
|
|
122
|
+
/>
|
|
123
|
+
{ inFlight && <Spinner /> }
|
|
124
|
+
</div>
|
|
125
|
+
{ selected && (
|
|
126
|
+
<Button isSecondary onClick={ () => setIsChanging( false ) }>
|
|
127
|
+
{ __( 'Cancel', 'newspack-blocks' ) }
|
|
128
|
+
</Button>
|
|
129
|
+
) }
|
|
130
|
+
</>
|
|
131
|
+
) }
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function CheckoutButtonEdit( props ) {
|
|
137
|
+
const { attributes, setAttributes, className } = props;
|
|
138
|
+
const { placeholder, style, text, product, price } = attributes;
|
|
139
|
+
|
|
140
|
+
const [ nyp, setNYP ] = useState( false );
|
|
141
|
+
function handleProduct( data ) {
|
|
142
|
+
const _nyp = {
|
|
143
|
+
isNYP: data?.meta_data?.some( meta => meta.key === '_nyp' && meta.value === 'yes' ),
|
|
144
|
+
suggestedPrice: data?.meta_data?.find( meta => meta.key === '_suggested_price' )?.value,
|
|
145
|
+
minPrice: data?.meta_data?.find( meta => meta.key === '_min_price' )?.value,
|
|
146
|
+
maxPrice: data?.meta_data?.find( meta => meta.key === '_maximum_price' )?.value,
|
|
147
|
+
};
|
|
148
|
+
setNYP( _nyp );
|
|
149
|
+
if ( ! price ) {
|
|
150
|
+
setAttributes( { price: _nyp?.suggestedPrice } );
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function setButtonText( newText ) {
|
|
155
|
+
// Remove anchor tags from button text content.
|
|
156
|
+
setAttributes( { text: newText.replace( /<\/?a[^>]*>/g, '' ) } );
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const borderProps = useBorderProps( attributes );
|
|
160
|
+
const colorProps = useColorProps( attributes );
|
|
161
|
+
const spacingProps = useSpacingProps( attributes );
|
|
162
|
+
const blockProps = useBlockProps();
|
|
163
|
+
return (
|
|
164
|
+
<>
|
|
165
|
+
<div
|
|
166
|
+
{ ...blockProps }
|
|
167
|
+
className={ classnames( blockProps.className, {
|
|
168
|
+
[ `wp-block-button` ]: true,
|
|
169
|
+
[ `has-custom-font-size` ]: blockProps.style.fontSize,
|
|
170
|
+
} ) }
|
|
171
|
+
>
|
|
172
|
+
<RichText
|
|
173
|
+
aria-label={ __( 'Button text' ) }
|
|
174
|
+
placeholder={ placeholder || __( 'Add text…' ) }
|
|
175
|
+
value={ text }
|
|
176
|
+
onChange={ value => setButtonText( value ) }
|
|
177
|
+
withoutInteractiveFormatting
|
|
178
|
+
className={ classnames(
|
|
179
|
+
className,
|
|
180
|
+
'wp-block-button__link',
|
|
181
|
+
'wp-block-newspack-blocks-checkout-button__button',
|
|
182
|
+
colorProps.className,
|
|
183
|
+
borderProps.className,
|
|
184
|
+
{
|
|
185
|
+
// For backwards compatibility add style that isn't
|
|
186
|
+
// provided via block support.
|
|
187
|
+
'no-border-radius': style?.border?.radius === 0,
|
|
188
|
+
}
|
|
189
|
+
) }
|
|
190
|
+
style={ {
|
|
191
|
+
...borderProps.style,
|
|
192
|
+
...colorProps.style,
|
|
193
|
+
...spacingProps.style,
|
|
194
|
+
} }
|
|
195
|
+
identifier="text"
|
|
196
|
+
/>
|
|
197
|
+
</div>
|
|
198
|
+
<InspectorControls>
|
|
199
|
+
<PanelBody title={ __( 'Product', 'newspack-blocks' ) }>
|
|
200
|
+
<ProductControl
|
|
201
|
+
value={ product }
|
|
202
|
+
price={ price }
|
|
203
|
+
onChange={ value => setAttributes( { product: value } ) }
|
|
204
|
+
onProduct={ handleProduct }
|
|
205
|
+
/>
|
|
206
|
+
</PanelBody>
|
|
207
|
+
{ nyp?.isNYP && (
|
|
208
|
+
<PanelBody title={ __( 'Name Your Price', 'newspack-blocks' ) }>
|
|
209
|
+
<p>
|
|
210
|
+
{ __(
|
|
211
|
+
'This product has "Name Your Price" toggled on. You can set the custom price for this checkout.',
|
|
212
|
+
'newspack-blocks'
|
|
213
|
+
) }
|
|
214
|
+
</p>
|
|
215
|
+
<p>
|
|
216
|
+
<strong>{ __( 'Suggested price:', 'newspack-blocks' ) }</strong>{ ' ' }
|
|
217
|
+
{ nyp.suggestedPrice || 0 }
|
|
218
|
+
{ nyp.minPrice && (
|
|
219
|
+
<>
|
|
220
|
+
<br />
|
|
221
|
+
<strong>{ __( 'Minimum price:', 'newspack-blocks' ) }</strong> { nyp.minPrice }
|
|
222
|
+
</>
|
|
223
|
+
) }
|
|
224
|
+
{ nyp.maxPrice && (
|
|
225
|
+
<>
|
|
226
|
+
<br />
|
|
227
|
+
<strong>{ __( 'Maximum price:', 'newspack-blocks' ) }</strong> { nyp.maxPrice }
|
|
228
|
+
</>
|
|
229
|
+
) }
|
|
230
|
+
</p>
|
|
231
|
+
<TextControl
|
|
232
|
+
type="number"
|
|
233
|
+
label={ __( 'Custom Price', 'newspack-blocks' ) }
|
|
234
|
+
placeholder={ nyp.suggestedPrice }
|
|
235
|
+
value={ price }
|
|
236
|
+
min={ parseFloat( nyp.minPrice ) || null }
|
|
237
|
+
max={ parseFloat( nyp.maxPrice ) || null }
|
|
238
|
+
onChange={ value => setAttributes( { price: value } ) }
|
|
239
|
+
/>
|
|
240
|
+
</PanelBody>
|
|
241
|
+
) }
|
|
242
|
+
</InspectorControls>
|
|
243
|
+
</>
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export default CheckoutButtonEdit;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
.newspack-checkout-button {
|
|
2
|
+
&__product-field {
|
|
3
|
+
&__selected {
|
|
4
|
+
.components-button {
|
|
5
|
+
display: block;
|
|
6
|
+
width: 100%;
|
|
7
|
+
text-align: left;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/* Workaround for hard-coded help text in FormTokenField. */
|
|
11
|
+
.components-form-token-field__help {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
&__tokenfield {
|
|
15
|
+
position: relative;
|
|
16
|
+
.components-spinner {
|
|
17
|
+
position: absolute;
|
|
18
|
+
top: 2em;
|
|
19
|
+
right: 0;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.wp-block-newspack-blocks-checkout-button {
|
|
26
|
+
[data-align='center'] & {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
}
|
|
30
|
+
&__button {
|
|
31
|
+
[data-align='full'] &,
|
|
32
|
+
[data-align='wide'] & {
|
|
33
|
+
width: 100%;
|
|
34
|
+
}
|
|
35
|
+
[data-align='center'] & {
|
|
36
|
+
margin-left: auto;
|
|
37
|
+
margin-right: auto;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { addFilter } from '@wordpress/hooks';
|
|
5
|
+
import { registerBlockType } from '@wordpress/blocks';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import { name, settings } from '.';
|
|
11
|
+
|
|
12
|
+
registerBlockType( name, settings );
|
|
13
|
+
|
|
14
|
+
addFilter(
|
|
15
|
+
'blockEditor.useSetting.before',
|
|
16
|
+
'newspack-blocks/add-border-radius-support',
|
|
17
|
+
( value, path, clientId, blockName ) => {
|
|
18
|
+
if ( path === 'border.radius' && blockName === 'newspack-blocks/checkout-button' ) {
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WordPress dependencies
|
|
3
|
+
*/
|
|
4
|
+
import { Icon, button } from '@wordpress/icons';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Internal dependencies
|
|
8
|
+
*/
|
|
9
|
+
import edit from './edit';
|
|
10
|
+
import metadata from './block.json';
|
|
11
|
+
import save from './save';
|
|
12
|
+
|
|
13
|
+
const { name } = metadata;
|
|
14
|
+
|
|
15
|
+
// Name must be exported separately.
|
|
16
|
+
export { name };
|
|
17
|
+
|
|
18
|
+
export const settings = {
|
|
19
|
+
...metadata,
|
|
20
|
+
|
|
21
|
+
icon: {
|
|
22
|
+
src: <Icon icon={ button } />,
|
|
23
|
+
foreground: '#36f',
|
|
24
|
+
},
|
|
25
|
+
edit,
|
|
26
|
+
save,
|
|
27
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/* eslint-disable @wordpress/no-unsafe-wp-apis */
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import classnames from 'classnames';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* WordPress dependencies
|
|
9
|
+
*/
|
|
10
|
+
import {
|
|
11
|
+
RichText,
|
|
12
|
+
useBlockProps,
|
|
13
|
+
__experimentalGetBorderClassesAndStyles as getBorderClassesAndStyles,
|
|
14
|
+
__experimentalGetColorClassesAndStyles as getColorClassesAndStyles,
|
|
15
|
+
__experimentalGetSpacingClassesAndStyles as getSpacingClassesAndStyles,
|
|
16
|
+
} from '@wordpress/block-editor';
|
|
17
|
+
|
|
18
|
+
export default function save( { attributes, className } ) {
|
|
19
|
+
const { textAlign, fontSize, style, text, product, price } = attributes;
|
|
20
|
+
|
|
21
|
+
if ( ! text || ! product ) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const borderProps = getBorderClassesAndStyles( attributes );
|
|
26
|
+
const colorProps = getColorClassesAndStyles( attributes );
|
|
27
|
+
const spacingProps = getSpacingClassesAndStyles( attributes );
|
|
28
|
+
const buttonClasses = classnames(
|
|
29
|
+
'wp-block-button__link',
|
|
30
|
+
colorProps.className,
|
|
31
|
+
borderProps.className,
|
|
32
|
+
{
|
|
33
|
+
[ `has-text-align-${ textAlign }` ]: textAlign,
|
|
34
|
+
// For backwards compatibility add style that isn't provided via
|
|
35
|
+
// block support.
|
|
36
|
+
'no-border-radius': style?.border?.radius === 0,
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
const buttonStyle = {
|
|
40
|
+
...borderProps.style,
|
|
41
|
+
...colorProps.style,
|
|
42
|
+
...spacingProps.style,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const wrapperClasses = classnames( className, {
|
|
46
|
+
[ `has-custom-font-size` ]: fontSize || style?.typography?.fontSize,
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div { ...useBlockProps.save( { className: wrapperClasses } ) }>
|
|
51
|
+
<form>
|
|
52
|
+
<RichText.Content
|
|
53
|
+
tagName="button"
|
|
54
|
+
className={ buttonClasses }
|
|
55
|
+
style={ buttonStyle }
|
|
56
|
+
value={ text }
|
|
57
|
+
/>
|
|
58
|
+
<input type="hidden" name="product_id" value={ product } />
|
|
59
|
+
<input type="hidden" name="newspack_checkout" value="1" />
|
|
60
|
+
{ price && <input type="hidden" name="price" value={ price } /> }
|
|
61
|
+
</form>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Checkout Button Block Front-End Functions
|
|
4
|
+
*
|
|
5
|
+
* @package Newspack_Blocks
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
namespace Newspack_Blocks\Checkout_Button;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Register the block.
|
|
12
|
+
*/
|
|
13
|
+
function register_block() {
|
|
14
|
+
register_block_type_from_metadata(
|
|
15
|
+
__DIR__ . '/block.json',
|
|
16
|
+
[
|
|
17
|
+
'render_callback' => __NAMESPACE__ . '\\render_callback',
|
|
18
|
+
]
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
add_action( 'init', __NAMESPACE__ . '\\register_block' );
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Render the block.
|
|
25
|
+
*
|
|
26
|
+
* @param array $attributes Block attributes.
|
|
27
|
+
* @param string $content Block content.
|
|
28
|
+
*
|
|
29
|
+
* @return string
|
|
30
|
+
*/
|
|
31
|
+
function render_callback( $attributes, $content ) {
|
|
32
|
+
\Newspack_Blocks\Modal_Checkout::enqueue_modal();
|
|
33
|
+
\Newspack_Blocks::enqueue_view_assets( 'checkout-button' );
|
|
34
|
+
return $content;
|
|
35
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.wp-block-newspack-blocks-checkout-button {
|
|
2
|
+
&.alignwide,
|
|
3
|
+
&.alignfull {
|
|
4
|
+
button {
|
|
5
|
+
width: 100%;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
&.aligncenter {
|
|
9
|
+
form {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
}
|
|
13
|
+
button {
|
|
14
|
+
margin-left: auto;
|
|
15
|
+
margin-right: auto;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|