Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/blocks/my-account-button/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Provides a reader account/sign-in button for sites using Newspack Reader Activat
- Signed in label (`signedInLabel`): Text shown when the reader is authenticated.
- Signed out label (`signedOutLabel`): Text shown when the reader is not authenticated.

### Display
The button also has the ability to toggle on/off the display of the icon or text label. You cannot toggle off both the icon and label at the same time.

When only the icon is visible, screenreaders will still be able to read the label, even if it's not visible. If this hidden label needs to be edited, it will need to be toggled back on in the editor, changed, and then hidden again.

## Editor behavior
- Use the toolbar toggle (Signed in / Signed out) to edit each label.

Expand Down
4 changes: 4 additions & 0 deletions src/blocks/my-account-button/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"signedOutLabel": {
"type": "string",
"default": "Sign in"
},
"className": {
"type": "string",
"default": ""
}
},
"supports": {
Expand Down
68 changes: 43 additions & 25 deletions src/blocks/my-account-button/class-my-account-button-block.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,31 @@ public static function render_block( $attrs ) {
$default_attrs = [
'signedInLabel' => __( 'My Account', 'newspack-plugin' ),
'signedOutLabel' => __( 'Sign in', 'newspack-plugin' ),
'className' => '',
];
$attrs = \wp_parse_args( $attrs, $default_attrs );

$is_signed_in = \is_user_logged_in();
$label = $is_signed_in ? $attrs['signedInLabel'] : $attrs['signedOutLabel'];
if ( '' === trim( (string) $label ) ) {
return '';
$is_signed_in = \is_user_logged_in();
$signed_in_label = '' === trim( (string) $attrs['signedInLabel'] ) ? $default_attrs['signedInLabel'] : $attrs['signedInLabel'];
$signed_out_label = '' === trim( (string) $attrs['signedOutLabel'] ) ? $default_attrs['signedOutLabel'] : $attrs['signedOutLabel'];
$label = $is_signed_in ? $signed_in_label : $signed_out_label;

// Display mode from block style class in className (default = icon + text).
$classes = explode( ' ', (string) $attrs['className'] );
if ( in_array( 'is-style-icon-only', $classes, true ) ) {
$show_label = false;
$show_icon = true;
} elseif ( in_array( 'is-style-text-only', $classes, true ) ) {
$show_label = true;
$show_icon = false;
} else {
$show_label = true;
$show_icon = true;
}

$account_url = self::get_account_url();

/** Do not render link for authenticated readers if account page doesn't exist. */
// Do not render link for authenticated readers if account page doesn't exist.
if ( empty( $account_url ) && \is_user_logged_in() ) {
return '';
}
Expand All @@ -118,8 +131,8 @@ public static function render_block( $attrs ) {
}

$labels = [
'signedin' => $attrs['signedInLabel'],
'signedout' => $attrs['signedOutLabel'],
'signedin' => $signed_in_label,
'signedout' => $signed_out_label,
];

$extra_classes = [
Expand All @@ -128,45 +141,50 @@ public static function render_block( $attrs ) {
'newspack-reader__account-link',
];

/** Get default wrapper attributes to extract custom classes */
// Get default wrapper attributes to extract custom classes.
$default_wrapper_attributes = \get_block_wrapper_attributes();

/** Extract custom classes (everything except the default block class) */
$default_block_class = 'wp-block-newspack-my-account-button';
$custom_classes = [];
// Extract custom classes (everything except the default block class).
$custom_classes = [];

/** Parse class attribute from default wrapper */
// Parse class attribute from default wrapper.
if ( \preg_match( '/class=["\']([^"\']+)["\']/', $default_wrapper_attributes, $matches ) ) {
$all_classes = \explode( ' ', $matches[1] );
foreach ( $all_classes as $class ) {
$class = \trim( $class );
/** Only include classes that contain "-size" (e.g., has-small-size) */
// Only include classes that contain "-size" (e.g., has-small-size).
if ( ! empty( $class ) && \strpos( $class, '-size' ) !== false ) {
$custom_classes[] = $class;
}
}
}

/** Build wrapper div classes */
$wrapper_div_classes = [ 'wp-block-buttons' ];
// Build wrapper div classes.
$wrapper_div_classes = [ 'wp-block-buttons', 'is-layout-flex' ];
if ( ! empty( $custom_classes ) ) {
$wrapper_div_classes = \array_merge( $wrapper_div_classes, $custom_classes );
}

$wrapper_attributes = \get_block_wrapper_attributes(
[
'class' => implode( ' ', $extra_classes ),
'href' => \esc_url_raw( $href ),
]
);
$wrapper_attribute_args = [
'class' => implode( ' ', $extra_classes ),
'href' => \esc_url_raw( $href ),
'data-newspack-logged-in' => $is_signed_in ? '1' : '0',
];
$wrapper_attributes = \get_block_wrapper_attributes( $wrapper_attribute_args );

$link = '<div class="' . \esc_attr( implode( ' ', $wrapper_div_classes ) ) . '">';
$link .= '<div class="wp-block-button">';
$link .= '<a ' . $wrapper_attributes . ' data-labels="' . \esc_attr( \wp_json_encode( $labels ) ) . '" ' . $should_modal_trigger . '>';
$link .= '<span class="wp-block-newspack-my-account-button__icon" aria-hidden="true">';
$link .= Newspack_UI_Icons::get_svg( 'account' );
$link .= '</span>';
$link .= '<span class="newspack-reader__account-link__label">' . \esc_html( $label ) . '</span>';
if ( $show_icon ) {
$link .= '<span class="wp-block-newspack-my-account-button__icon" aria-hidden="true">';
$link .= Newspack_UI_Icons::get_svg( 'account' );
$link .= '</span>';
}
$label_classes = [ 'newspack-reader__account-link__label' ];
if ( ! $show_label ) {
$label_classes[] = 'screen-reader-text';
}
$link .= '<span class="' . \esc_attr( implode( ' ', $label_classes ) ) . '">' . \esc_html( $label ) . '</span>';
$link .= '</a>';
$link .= '</div>';
$link .= '</div>';
Expand Down
79 changes: 46 additions & 33 deletions src/blocks/my-account-button/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,19 @@ import {
} from '@wordpress/block-editor';
import { ToolbarButton, ToolbarGroup } from '@wordpress/components';

/**
* Internal dependencies
*/
function MyAccountButtonEdit( { attributes, setAttributes } ) {
const { signedInLabel, signedOutLabel, style, className: customClassName } = attributes;
const { signedInLabel, signedOutLabel, style, className: blockClassName } = attributes;
const borderProps = useBorderProps( attributes );
const colorProps = useColorProps( attributes );
const spacingProps = useSpacingProps( attributes );
const isIconOnly = ( blockClassName || '' ).includes( 'is-style-icon-only' );
const isTextOnly = ( blockClassName || '' ).includes( 'is-style-text-only' );
const isLabelVisible = ! isIconOnly;
const isIconVisible = ! isTextOnly;

const blockProps = useBlockProps( {
className: classnames(
blockClassName,
'wp-block-button__link',
'newspack-reader__account-link',
'wp-block-newspack-my-account-button__link',
Expand All @@ -51,52 +54,62 @@ function MyAccountButtonEdit( { attributes, setAttributes } ) {
...spacingProps.style,
},
} );
const isReaderActivationEnabled = typeof newspack_blocks === 'undefined' || newspack_blocks.has_reader_activation;

const isReaderActivationEnabled = typeof newspack_blocks === 'undefined' || newspack_blocks.has_reader_activation;
const [ previewState, setPreviewState ] = useState( 'signedout' );
const isSignedOutPreview = previewState === 'signedout';
const activeLabel = isSignedOutPreview ? signedOutLabel : signedInLabel;
const placeholderText = isSignedOutPreview ? __( 'Sign in', 'newspack-plugin' ) : __( 'My Account', 'newspack-plugin' );

function setButtonText( newText ) {
const cleaned = stripHTML( newText );
setAttributes( isSignedOutPreview ? { signedOutLabel: cleaned } : { signedInLabel: cleaned } );
setAttributes( isSignedOutPreview ? { signedOutLabel: stripHTML( newText ) } : { signedInLabel: stripHTML( newText ) } );
}

if ( ! isReaderActivationEnabled ) {
return <div { ...blockProps } style={ { ...blockProps.style, display: 'none' } } />;
}

return ! isReaderActivationEnabled ? (
<div { ...blockProps } style={ { ...blockProps.style, display: 'none' } } />
) : (
return (
<>
<BlockControls>
<ToolbarGroup>
<ToolbarButton
isPressed={ isSignedOutPreview }
onClick={ () => setPreviewState( 'signedout' ) }
style={ { paddingLeft: '12px', paddingRight: '12px' } }
>
{ __( 'Signed out', 'newspack-plugin' ) }
</ToolbarButton>
<ToolbarButton
isPressed={ ! isSignedOutPreview }
onClick={ () => setPreviewState( 'signedin' ) }
style={ { paddingLeft: '12px', paddingRight: '12px' } }
>
{ __( 'Signed in', 'newspack-plugin' ) }
</ToolbarButton>
</ToolbarGroup>
</BlockControls>
<div className={ classnames( 'wp-block-buttons', customClassName ) }>
{ isLabelVisible && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When icon-only style is selected, isLabelVisible is false, so the "Signed out"/"Signed in" toolbar toggle disappears entirely. The user cannot edit the screen reader label text for the signed-in state without switching styles first, and then back.
I'm not sure if there's a solution for this, since it needs to render the text in order to be modified, or if this is even an issue 🤔.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah but I think it's OK since it uses the default aria-labels

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a little funky, but I think it's probably okay as is for now -- or at least the kind of thing that should be covered in the documentation (how to edit the hidden label), and if we get a lot of feedback about friction, we can revisit 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Readme has been updated in cf68793!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say keep it as it is for now. If we get feedback about this, we can always add 2 textcontrols to the sidebar

<BlockControls>
<ToolbarGroup>
<ToolbarButton
icon={ false }
isPressed={ isSignedOutPreview }
label={ __( 'Signed out', 'newspack-plugin' ) }
onClick={ () => setPreviewState( 'signedout' ) }
style={ { paddingLeft: '12px', paddingRight: '12px' } }
>
{ __( 'Signed out', 'newspack-plugin' ) }
</ToolbarButton>
<ToolbarButton
icon={ false }
isPressed={ ! isSignedOutPreview }
label={ __( 'Signed in', 'newspack-plugin' ) }
onClick={ () => setPreviewState( 'signedin' ) }
style={ { paddingLeft: '12px', paddingRight: '12px' } }
>
{ __( 'Signed in', 'newspack-plugin' ) }
</ToolbarButton>
</ToolbarGroup>
</BlockControls>
) }
<div className={ classnames( 'wp-block-buttons', 'is-layout-flex', blockClassName ) }>
<div className="wp-block-button">
<div { ...blockProps }>
<span className="wp-block-newspack-my-account-button__icon" aria-hidden="true">
{ icon }
</span>
{ isIconVisible && (
<span className="wp-block-newspack-my-account-button__icon" aria-hidden="true">
{ icon }
</span>
) }
<RichText
tagName="span"
className={ ! isLabelVisible ? 'screen-reader-text' : undefined }
aria-label={ __( 'Button text', 'newspack-plugin' ) }
placeholder={ placeholderText }
value={ activeLabel || '' }
onChange={ value => setButtonText( value ) }
onChange={ setButtonText }
withoutInteractiveFormatting
/>
</div>
Expand Down
18 changes: 18 additions & 0 deletions src/blocks/my-account-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,30 @@ import './style.scss';
/**
* WordPress dependencies
*/
import { registerBlockStyle } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
import { button as icon } from '@wordpress/icons';

const { name } = metadata;

export { metadata, name };

registerBlockStyle( name, {
name: 'default',
label: __( 'Default', 'newspack-plugin' ),
isDefault: true,
} );

registerBlockStyle( name, {
name: 'icon-only',
label: __( 'Icon only', 'newspack-plugin' ),
} );

registerBlockStyle( name, {
name: 'text-only',
label: __( 'Text only', 'newspack-plugin' ),
} );

export const settings = {
title: metadata.title,
icon: {
Expand Down
15 changes: 12 additions & 3 deletions src/blocks/my-account-button/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
&__icon {
display: grid;
place-items: center;
}

svg {
fill: currentcolor;
height: max(24px, 1.5em);
width: max(24px, 1.5em);
}

&:not(:has(.screen-reader-text)) {
svg {
fill: currentcolor;
height: max(24px, 1.5em);
margin-left: calc( max(4px, 0.25em) * -1);
margin-right: calc( max(4px, 0.25em) * -1);
width: max(24px, 1.5em);
}
}

.wp-block-buttons > .wp-block-button:has(&) {
display: inline-flex;
}
}
6 changes: 6 additions & 0 deletions src/reader-activation-auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ window.newspackRAS.push( readerActivation => {
const labels = JSON.parse( link.getAttribute( 'data-labels' ) );
const labelEl = link.querySelector( '.newspack-reader__account-link__label' );
if ( labelEl ) {
// Change the label for the My Account button only.
const isLoggedIn = link.getAttribute( 'data-newspack-logged-in' ) === '1';
if ( isLoggedIn ) {
labelEl.textContent = labels.signedin;
return;
}
labelEl.textContent = reader?.authenticated ? labels.signedin : labels.signedout;

// Set my account link href if the reader is authenticated.
Expand Down
Loading
Loading