Skip to content

Commit

Permalink
feat(donate-block): hide buttons if only one frequency is available (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
adekbadek authored Nov 15, 2024
1 parent 7a73b9d commit 043591e
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 68 deletions.
47 changes: 39 additions & 8 deletions src/blocks/donate/edit/FrequencyBasedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import { RichText } from '@wordpress/block-editor';
* Internal dependencies
*/
import { AmountValueInput } from './components';
import { getColorForContrast, getFrequencyLabel } from '../utils';
import { getColorForContrast, getFrequencyLabel, getFrequencyLabelWithAmount } from '../utils';
import { FREQUENCIES } from '../consts';
import type { ComponentProps, DonationFrequencySlug } from '../types';
import { updateBlockClassName, getFormData } from '../view'

const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) => {
// Unique identifier to prevent collisions with other Donate blocks' labels.
Expand All @@ -26,10 +27,25 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =

const formRef = useRef< HTMLFormElement >( null );

// Add event listeners to the form.
useEffect( () => {
if ( formRef.current !== null ) {
const parentElement = formRef.current.closest('.wpbnbd');
if ( parentElement ) {
updateBlockClassName( parentElement, getFormData( formRef.current ));
}
formRef.current.addEventListener('change', () => {
if ( formRef.current !== null && parentElement ) {
updateBlockClassName( parentElement, getFormData( formRef.current ));
}
})
}
}, [] );

// Update selected frequency when available frequencies change.
useEffect( () => {
if ( formRef.current ) {
const formValues = Object.fromEntries( new FormData( formRef.current ) );
const formValues = getFormData( formRef.current );
if ( ! formValues.donation_frequency && formRef.current.elements ) {
const frequencyRadioInput = formRef.current.elements[ 0 ];
if ( frequencyRadioInput instanceof HTMLInputElement ) {
Expand Down Expand Up @@ -92,10 +108,17 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
// This code is fired on tab select and updates aria elements, tabindex states, and radio buttons
const displayAmount = ( amount: number ) => amount.toFixed( 2 ).replace( /\.?0*$/, '' );

const renderFormHeader = () => {
return ! rendersSingleFrequency && (
<div className="tab-container">{ availableFrequencies.map( renderTab ) }</div>
)
}
const rendersSingleFrequency = availableFrequencies.length === 1

const renderUntieredForm = () => (
<div className="wp-block-newspack-blocks-donate__options">
<div className="wp-block-newspack-blocks-donate__frequencies frequencies">
<div className="tab-container">{ availableFrequencies.map( renderTab ) }</div>
{renderFormHeader()}
{ availableFrequencies.map( frequencySlug => {
const untieredAmount = amounts[ frequencySlug ][ 3 ];
return (
Expand All @@ -112,6 +135,7 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
htmlFor={ 'newspack-' + frequencySlug + '-' + uid + '-untiered-input' }
>
{ __( 'Donation amount', 'newspack-blocks' ) }
{ getFrequencyLabel( frequencySlug, true ) }
</label>
<div className="wp-block-newspack-blocks-donate__money-input money-input">
<span className="currency">{ settings.currencySymbol }</span>
Expand Down Expand Up @@ -140,7 +164,7 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
>
<div
dangerouslySetInnerHTML={ {
__html: getFrequencyLabel( untieredAmount, frequencySlug ),
__html: getFrequencyLabelWithAmount( untieredAmount, frequencySlug ),
} }
/>
</label>
Expand All @@ -157,7 +181,7 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
const renderTieredForm = () => (
<div className="wp-block-newspack-blocks-donate__options">
<div className="wp-block-newspack-blocks-donate__frequencies frequencies">
<div className="tab-container">{ availableFrequencies.map( renderTab ) }</div>
{ renderFormHeader()}
{ availableFrequencies.map( frequencySlug => (
<div
className="wp-block-newspack-blocks-donate__frequency frequency"
Expand All @@ -171,6 +195,9 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
const id = `newspack-tier-${ frequencySlug }-${ uid }-${
isOtherTier ? 'other' : index
}`;
const tierLabel = isOtherTier
? __( 'Other', 'newspack-blocks' )
: `${settings.currencySymbol}${displayAmount( suggestedAmount )}`
return (
<div
className={ classNames(
Expand All @@ -190,14 +217,13 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
defaultChecked={ index === 1 }
/>
<label className="tier-select-label tier-label" htmlFor={ id }>
{ isOtherTier
? __( 'Other', 'newspack-blocks' )
: settings.currencySymbol + displayAmount( suggestedAmount ) }
{ tierLabel }
</label>
{ isOtherTier ? (
<>
<label className="odl" htmlFor={ id + '-other-input' }>
{ __( 'Donation amount', 'newspack-blocks' ) }
{ getFrequencyLabel( frequencySlug, true ) }
</label>
<div className="wp-block-newspack-blocks-donate__money-input money-input">
<span className="currency">{ settings.currencySymbol }</span>
Expand All @@ -208,6 +234,11 @@ const FrequencyBasedLayout = ( props: { isTiered: boolean } & ComponentProps ) =
</div>
);
} ) }
{ rendersSingleFrequency ? (
<div className='wp-block-newspack-blocks-donate__frequency-label'>
{getFrequencyLabel( frequencySlug, true )}
</div>
) : null }
</div>
</div>
) ) }
Expand Down
38 changes: 20 additions & 18 deletions src/blocks/donate/edit/TierBasedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import classNames from 'classnames';
* Internal dependencies
*/
import type { ComponentProps, DonateBlockAttributes, TierBasedOptionValue } from '../types';
import { getColorForContrast, getFrequencyLabel } from '../utils';
import { getColorForContrast, getFrequencyLabelWithAmount } from '../utils';
import { FREQUENCIES, DISABLED_IN_TIERS_BASED_LAYOUT_TIER_INDEX } from '../consts';

const TierBasedLayout = ( props: ComponentProps ) => {
Expand Down Expand Up @@ -44,22 +44,24 @@ const TierBasedLayout = ( props: ComponentProps ) => {

return (
<form className="wpbnbd__tiers" onSubmit={ e => e.preventDefault() }>
<div className="wpbnbd__tiers__selection">
{ availableFrequencies.map( frequencySlug => {
const isActive = currentFrequency === frequencySlug;
return (
<button
key={ frequencySlug }
className={ classNames( 'wpbnbd__button', {
'wpbnbd__button--active': isActive,
} ) }
onClick={ () => setCurrencyFrequency( frequencySlug ) }
>
{ FREQUENCIES[ frequencySlug ] }
</button>
);
} ) }
</div>
{ availableFrequencies.length > 1 && (
<div className="wpbnbd__tiers__selection">
{ availableFrequencies.map( frequencySlug => {
const isActive = currentFrequency === frequencySlug;
return (
<button
key={ frequencySlug }
className={ classNames( 'wpbnbd__button', {
'wpbnbd__button--active': isActive,
} ) }
onClick={ () => setCurrencyFrequency( frequencySlug ) }
>
{ FREQUENCIES[ frequencySlug ] }
</button>
);
} ) }
</div>
)}
<div className="wpbnbd__tiers__options">
{ displayedAmounts.map( ( amount, index ) => {
const recommendLabel = attributes.tiersBasedOptions[ index ].recommendLabel || '';
Expand Down Expand Up @@ -94,7 +96,7 @@ const TierBasedLayout = ( props: ComponentProps ) => {
<div className="wpbnbd__tiers__amount">
<div
dangerouslySetInnerHTML={ {
__html: getFrequencyLabel( amount, currentFrequency ),
__html: getFrequencyLabelWithAmount( amount, currentFrequency ),
} }
/>
</div>
Expand Down
8 changes: 8 additions & 0 deletions src/blocks/donate/frequency-based/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,11 @@
}
}
}

.wp-block-newspack-blocks-donate {
&__frequency-label {
display: flex;
align-items: center;
padding-left: 8px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,33 @@ private static function render_footer( $attributes ) {
return ob_get_clean();
}

/**
* Render the form header.
*
* @param array $configuration The donations settings.
* @param string $uid ID of the block.
*/
private static function render_form_header( $configuration, $uid ) {
?>
<?php if ( ! self::renders_single_frequency( $configuration ) ) : ?>
<div role='tablist' class='tab-container'>
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>
<?php echo self::render_frequency_tab( $frequency_slug, $frequency_name, $uid, $configuration ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php
}

/**
* Does the block render just a single frequency?
*
* @param array $configuration The donations settings.
*/
private static function renders_single_frequency( $configuration ) {
return count( $configuration['frequencies'] ) === 1;
}

/**
* Render the frequency-based layout.
*
Expand Down Expand Up @@ -128,13 +155,7 @@ class="untiered <?php echo esc_html( $configuration['container_classnames'] ); ?
<?php echo self::render_hidden_form_inputs( $attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class='wp-block-newspack-blocks-donate__options'>
<div class='wp-block-newspack-blocks-donate__frequencies frequencies'>

<div role='tablist' class='tab-container'>
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>
<?php echo self::render_frequency_tab( $frequency_slug, $frequency_name, $uid, $configuration ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php endforeach; ?>
</div>

<?php echo self::render_form_header( $configuration, $uid ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>
<?php
$formatted_amount = $configuration['amounts'][ $frequency_slug ][3];
Expand All @@ -155,6 +176,7 @@ class='donate-label'
for='newspack-<?php echo esc_attr( $frequency_slug . '-' . $uid ); ?>-untiered-input'
>
<?php echo esc_html__( 'Donation amount', 'newspack-blocks' ); ?>
<?php echo esc_html( trim( self::get_frequency_label( $frequency_slug, true ) ) ); ?>
</label>
<div class='wp-block-newspack-blocks-donate__money-input money-input'>
<span class='currency'>
Expand Down Expand Up @@ -206,14 +228,8 @@ class="tiered <?php echo esc_html( $configuration['container_classnames'] ); ?>"
<?php echo self::render_hidden_form_inputs( $attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div class='wp-block-newspack-blocks-donate__options'>
<div class='wp-block-newspack-blocks-donate__frequencies frequencies'>
<div role='tablist' class='tab-container'>
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>
<?php echo self::render_frequency_tab( $frequency_slug, $frequency_name, $uid, $configuration ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php endforeach; ?>
</div>

<?php echo self::render_form_header( $configuration, $uid ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>

<div
class='wp-block-newspack-blocks-donate__frequency frequency'
id='tab-panel-<?php echo esc_attr( $frequency_slug . '-' . $uid ); ?>'
Expand Down Expand Up @@ -246,6 +262,7 @@ class='odl'
for='newspack-tier-<?php echo esc_attr( $frequency_slug . '-' . $uid ); ?>-other-input'
>
<?php echo esc_html__( 'Donation amount', 'newspack-blocks' ); ?>
<?php echo esc_html( trim( self::get_frequency_label( $frequency_slug, true ) ) ); ?>
</label>
<div class='wp-block-newspack-blocks-donate__money-input money-input'>
<span class='currency'>
Expand Down Expand Up @@ -279,6 +296,14 @@ class='tier-select-label tier-label'
?>
</div>
<?php endforeach; ?>
<?php if ( self::renders_single_frequency( $configuration ) ) : ?>
<div class='wp-block-newspack-blocks-donate__frequency-label'>
<div>
<?php echo esc_html( trim( self::get_frequency_label( $frequency_slug, true ) ) ); ?>

</div>
</div>
<?php endif; ?>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,22 @@ class="<?php echo esc_attr( $configuration['container_classnames'] ); ?>"
<?php echo self::render_hidden_form_inputs( $attributes ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<input type="hidden" name="<?php echo esc_attr( self::FREQUENCY_PARAM ); ?>" value="<?php echo esc_attr( $intial_selected_frequency ); ?>">
<div class="wpbnbd__tiers">
<div class="wpbnbd__tiers__selection">
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>
<button
type="button"
data-frequency-slug="<?php echo esc_attr( $frequency_slug ); ?>"
data-frequency-label="<?php echo esc_attr( self::get_frequency_label( $frequency_slug ) ); ?>"
class="wpbnbd__button <?php echo $intial_selected_frequency === $frequency_slug ? 'wpbnbd__button--active' : ''; ?>"
><?php echo esc_html( $frequency_name ); ?></button>
<?php endforeach; ?>
</div>
<?php if ( count( $configuration['frequencies'] ) > 1 ) : ?>
<div class="wpbnbd__tiers__selection">
<?php foreach ( $configuration['frequencies'] as $frequency_slug => $frequency_name ) : ?>
<button
type="button"
data-frequency-slug="<?php echo esc_attr( $frequency_slug ); ?>"
data-frequency-label="<?php echo esc_attr( self::get_frequency_label( $frequency_slug ) ); ?>"
class="wpbnbd__button <?php echo $intial_selected_frequency === $frequency_slug ? 'wpbnbd__button--active' : ''; ?>"
><?php echo esc_html( $frequency_name ); ?></button>
<?php endforeach; ?>
</div>
<?php endif; ?>
<?php
$keys = array_keys( $configuration['frequencies'] );
$frequency_slug = reset( $keys );
?>
<div class="wpbnbd__tiers__options">
<?php foreach ( $displayed_amounts as $index => $amount ) : ?>
<?php
Expand Down
8 changes: 8 additions & 0 deletions src/blocks/donate/styles/view.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@
mark {
background-color: transparent;
}

&--selected {
&-other {
.wp-block-newspack-blocks-donate__frequency-label {
display: none;
}
}
}
}
28 changes: 17 additions & 11 deletions src/blocks/donate/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,22 @@ export const getMigratedAmount = (
};

export const getFrequencyLabel = (
frequencySlug: DonationFrequencySlug,
hideOnceLabel = false
) => {
// eslint-disable-next-line no-nested-ternary
return frequencySlug === 'once'
? hideOnceLabel
? ''
: __( ' once', 'newspack-blocks' )
: sprintf(
// Translators: %s is the frequency (e.g. per month, per year).
_x( ' per %s', 'per `Frequency`', 'newspack-blocks' ),
frequencySlug
);
}

export const getFrequencyLabelWithAmount = (
amount: number,
frequencySlug: DonationFrequencySlug,
hideOnceLabel = false
Expand Down Expand Up @@ -88,17 +104,7 @@ export const getFrequencyLabel = (

const formattedAmount = ( amount || 0 ).toFixed( 2 ).replace( /\.?0*$/, '' );

const frequency =
// eslint-disable-next-line no-nested-ternary
frequencySlug === 'once'
? hideOnceLabel
? ''
: __( ' once', 'newspack-blocks' )
: sprintf(
// Translators: %s is the frequency (e.g. per month, per year).
_x( ' per %s', 'per `Frequency`', 'newspack-blocks' ),
frequencySlug
);
const frequency = getFrequencyLabel(frequencySlug, hideOnceLabel)

return template
.replace( 'AMOUNT_PLACEHOLDER', formattedAmount )
Expand Down
5 changes: 0 additions & 5 deletions src/blocks/donate/view.js

This file was deleted.

Loading

0 comments on commit 043591e

Please sign in to comment.