Skip to content

feat[my-account-block]: add option to toggle off icon/text, and update tests#4443

Merged
laurelfulford merged 14 commits intotrunkfrom
feat/my-account-button-display
Feb 11, 2026
Merged

feat[my-account-block]: add option to toggle off icon/text, and update tests#4443
laurelfulford merged 14 commits intotrunkfrom
feat/my-account-button-display

Conversation

@laurelfulford
Copy link
Contributor

All Submissions:

Changes proposed in this Pull Request:

This PR adds an option to hide either the icon or label on the My Account Button block (but not both at the same time).

As part of that, I changed how the button acts if you don't give it a text label (instead of not showing anything, it will fallback to the default labels) -- when it's hidden in the settings, the label is still used as screen reader text so we don't want it to be empty even if it's not visible.

I also updated the tests to check for the default (vs. making sure empty strings were empty), and tweaked the behaviour to make sure logged in admins (not just readers) would see the My Account labels - I thought this was working before but I was seeing Sign In in trunk.

See NPPD-1183.

How to test the changes in this Pull Request:

  1. Apply this PR and run npm run build. As a bonus you can also test this alongside feat: make My Account button only show icon on mobile newspack-block-theme#406, but it's not required.
  2. If using the default header patterns, the button should already be in the header. If not, add the My Account Button block to the header.
  3. Click on the button and confirm you have a Display panel under the Settings tab, with an option to Display label and Display icon. Both should be enabled by default:
CleanShot 2026-02-02 at 10 48 31@2x
  1. Try turning of each option and confirm that the button updates appropriately (hiding the text or the icon). Confirm that you can't turn off both options at once -- if you try to turn off say, the icon, the label should switch to visible if it isn't already, and vis versa.
  2. Try changing the text labels on each state of the button (Signed in, Signed out), turn off the Show label toggle, and view on the front end.
  3. Confirm you only see the icons; when you inspect the icon, you should see your label text wrapped in a screen-reader-text span.
  4. Try signing in/signing up in an incognito window, and confirm hidden text is right (that you can see the Signed out text in the markup when you're not logged in, and Signed in text when you are).
  5. Try editing the header again and switching the settings so you can see the text, but not the icon; repeat step 7.
  6. Try editing the text label of each button and leave it blank; confirm you can still see the placeholder in the editor.
  7. Publish your changes and confirm you see the default text on the front-end (Sign In and My Account).
  8. Run the tests just to make sure they come back okay.

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully ran tests with your changes locally?

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds display controls to the My Account Button block, allowing users to selectively hide either the icon or label text, while ensuring at least one element remains visible for usability. The PR also improves the empty label fallback behavior and fixes an issue where logged-in admins were seeing incorrect button labels.

Changes:

  • Added showLabel and showIcon boolean attributes with UI toggles in the Inspector Controls
  • Updated empty label handling to fallback to defaults instead of rendering nothing
  • Added data-wp-logged-in attribute to preserve correct labels for logged-in WordPress users
  • Updated tests to verify fallback behavior for empty labels

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/blocks/my-account-button/block.json Added showLabel and showIcon boolean attributes with default values of true
src/blocks/my-account-button/edit.js Implemented Inspector Controls with toggle controls and mutual exclusivity logic, added conditional rendering for icon/label visibility
src/blocks/my-account-button/class-my-account-button-block.php Added showLabel/showIcon attribute handling, conditional rendering logic, screen-reader-text class for hidden labels, and data-wp-logged-in attribute
src/reader-activation-auth/index.js Added check for logged-in WordPress users to preserve correct label text and prevent unnecessary reader authentication checks
tests/unit-tests/class-test-my-account-button-block.php Split empty label test into separate signed-in/signed-out tests, updated assertions to verify fallback to default labels
src/blocks/my-account-button/README.md Added documentation for the new Display toggle feature

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@thomasguillot thomasguillot force-pushed the feat/my-account-button-display branch from 8d2f75a to 666a61a Compare February 3, 2026 18:02
@thomasguillot thomasguillot force-pushed the feat/my-account-button-display branch from 666a61a to d315db9 Compare February 3, 2026 18:04
@Automattic Automattic deleted a comment from laurelfulford Feb 3, 2026
@thomasguillot
Copy link
Contributor

thomasguillot commented Feb 3, 2026

Here's an update, using styles: d315db9

image

@laurelfulford
Copy link
Contributor Author

@thomasguillot Looks good to me! 🙂 Now we just need to see what an uninvolved third-party has to say!

Copy link
Member

@rbcorrales rbcorrales left a comment

Choose a reason for hiding this comment

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

Nice approach using block styles instead of custom toggles! Left a few inline comments, the main ones being the double useBlockProps() call in the editor and the data-wp-* namespace on the logged-in attribute. The rest is mostly minor.

const spacingProps = useSpacingProps( attributes );

// Block style comes from the Styles panel (wrapper) or saved className.
const blockWrapperProps = useBlockProps();
Copy link
Member

Choose a reason for hiding this comment

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

Calling useBlockProps() twice in the same component is not a supported pattern. Each call generates its own ref and block binding, so the editor will bind internal state (selection, focus, drag) to whichever ref was registered last. The first call here is never attached to a DOM node, which can cause subtle bugs.

The is-style-* class is already available on attributes.className (already serialized by WP). You can technically derive the style variant directly from blockClassName without this extra call:

const isIconOnly = ( blockClassName || '' ).includes( 'is-style-icon-only' );
const isTextOnly = ( blockClassName || '' ).includes( 'is-style-text-only' );

Copy link
Contributor

Choose a reason for hiding this comment

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

$wrapper_attribute_args = [
'class' => implode( ' ', $extra_classes ),
'href' => \esc_url_raw( $href ),
'data-wp-logged-in' => $is_signed_in ? '1' : '0',
Copy link
Member

Choose a reason for hiding this comment

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

The data-wp-* prefix is used by WordPress Interactivity API, and custom plugins should avoid it to prevent future collisions. Can we rename it to something different, like data-newspack-logged-in?

Also, this attribute explicitly states the user's authentication state in the DOM, though it's already inferable from the button's href (hashtag vs anything else). Maybe this is not really needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @rbcorrales! I updated the attribute name in 81ee30d, but left it -- it's a little yucky, but the My Account Button block behaves a little different than the My Account link that's inserted into the theme (the latter isn't visible for logged in non-readers, and when it is in the Customizer, it says 'Sign In'). The attribute seemed like the nicest way to switch it in just the one spot.


/** Display mode from block style class in className (default = icon + text). */
$wrapper_class = (string) $attrs['className'];
if ( \strpos( $wrapper_class, 'is-style-icon-only' ) !== false ) {
Copy link
Member

Choose a reason for hiding this comment

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

A hypothetical additional class like is-style-icon-only-alt would also match. A more robust approach:

$classes = explode( ' ', (string) $attrs['className'] );
if ( in_array( 'is-style-icon-only', $classes, true ) ) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call! Fixed in a49f0e0.

</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

$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). */
Copy link
Member

Choose a reason for hiding this comment

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

Nit: WPCS recommends // for inline comments. /** */ style is reserved for docblocks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Not on this PR, but $default_block_class on line 148 is assigned but never used.

Copy link
Contributor

Choose a reason for hiding this comment

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

Removed as part of 9fed074

Comment on lines 36 to 37
const isIconOnly = className.includes( 'is-style-icon-only' );
const isTextOnly = className.includes( 'is-style-text-only' );
Copy link
Member

Choose a reason for hiding this comment

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

Similar comment about class names matching.

Copy link
Contributor

Choose a reason for hiding this comment

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

@github-actions github-actions bot added the [Status] Needs Changes or Feedback The issue or pull request needs action from the original creator label Feb 10, 2026
@thomasguillot
Copy link
Contributor

@laurelfulford I tried to fix some of the things @rbcorrales mentioned. I haven’t touched the PHP, if you’d like to take care of that.

@laurelfulford
Copy link
Contributor Author

Thanks for the review, @rbcorrales, and for the fixes, @thomasguillot!

I think I got the rest, but let me know if anything still seems funky. I'm going to update the Docs in Linear to also reflect the little "gotcha" around editing the label when hidden.

@laurelfulford laurelfulford removed the [Status] Needs Changes or Feedback The issue or pull request needs action from the original creator label Feb 10, 2026
@thomasguillot thomasguillot removed their request for review February 11, 2026 13:46
@thomasguillot thomasguillot force-pushed the feat/my-account-button-display branch from 40a4021 to f07b889 Compare February 11, 2026 13:50
@thomasguillot thomasguillot force-pushed the feat/my-account-button-display branch from f07b889 to 86d6e24 Compare February 11, 2026 14:01
Copy link
Member

@rbcorrales rbcorrales left a comment

Choose a reason for hiding this comment

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

Thanks for addressing all the feedback @laurelfulford @thomasguillot! Everything looks good, but one thing that wasn't addressed: the class matching in edit.js still uses String.includes(), which could match partial class names (e.g. is-style-icon-only-alt). The PHP side was correctly updated to explode + in_array, but the JS side wasn't. The equivalent fix:

const classes = ( blockClassName || '' ).split( ' ' );
const isIconOnly = classes.includes( 'is-style-icon-only' );
const isTextOnly = classes.includes( 'is-style-text-only' );

Approving, but would be great to get that last item in before merging.

@github-actions github-actions bot added [Status] Approved The pull request has been reviewed and is ready to merge and removed [Status] Needs Review The issue or pull request needs to be reviewed labels Feb 11, 2026
@laurelfulford
Copy link
Contributor Author

Thanks @rbcorrales!

Everything looks good, but one thing that wasn't addressed: the class matching in edit.js still uses String.includes()...

🤦‍♀️ This was entirely my bad, and is fixed in b47c2a2 -- thank you for catching that!

@laurelfulford laurelfulford merged commit 5082b55 into trunk Feb 11, 2026
7 checks passed
@laurelfulford laurelfulford deleted the feat/my-account-button-display branch February 11, 2026 22:22
@github-actions
Copy link

Hey @laurelfulford, good job getting this PR merged! 🎉

Now, the needs-changelog label has been added to it.

Please check if this PR needs to be included in the "Upcoming Changes" and "Release Notes" doc. If it doesn't, simply remove the label.

If it does, please add an entry to our shared document, with screenshots and testing instructions if applicable, then remove the label.

Thank you! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-changelog [Status] Approved The pull request has been reviewed and is ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants