Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve implementation of the 'Show button text labels' preference #61763

Open
afercia opened this issue May 17, 2024 · 11 comments · May be fixed by #61824
Open

Improve implementation of the 'Show button text labels' preference #61763

afercia opened this issue May 17, 2024 · 11 comments · May be fixed by #61824
Assignees
Labels
[Feature] Show button text labels A preference in the Post and Site Editor that makes buttons show text instead of icons [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Editor /packages/editor [Status] In Progress Tracking issues with work in progress [Type] Enhancement A suggestion for improvement.

Comments

@afercia
Copy link
Contributor

afercia commented May 17, 2024

Description

The 'Show button text labels' preference is an usability and accessibility features that makes icon buttons show visible text instead of icons.

It's not just accessibility. It's general usability, as some users may just prefer visible text. It has been inspired by the similar macOS finder preference, where users may choose to show buttons with: Icon and text, Icon only, Text only. Screenshot:

Screenshot 2024-05-17 at 15 17 04

So far, this feature isn't 'built-in' in the components. Rather, it is implemented by the means of 'local overrides' of the buttons styling. It is also worth reminding that it is not implemented for all buttons but only for some of them. The related CSS is scattered all around in several files and compoennts. It's difficult to maintain and it's duplicated code.

Over time, this feature faced several breakages as it is often missed in the design of new features in the first place and often missed during developing and manual testing. #61761 is the most recent breakage.

The Button component isn't aware of this preference, as it's more a preference of the environment the component lives in. As such, an architectural choice should me made first on whether the Button componetn should support this feature natively or keeping the current approach based on local overrides. As I see it, considering the several breakages in the history of this project related to this feature, the former option would be preferable.

I would appreciate any thoughts and feedback on the best way to make this feature more solid, incorporated in any new design, and better testable.

In the meantime, I'd think there's a few points that can be addressed soon to make this feature better meintenable. For example, looking at the CSS used for local overrides, there's a few things that are duplicated all around and could use a mixin:

What the various CSS overrides always do is basically the following:

  • Hide the button SVG icon.
  • Generate the button visible text by the means of CSS pseudo generated content that rargets the button aria-label attribute.
  • Reset the button width to auto.

As a start, a new mixin could be used to have this rule in a centralized place and avoid code duplication. The mixin could be then extended to incorporate other styling, as much as possible. Small adjustments on a per component base would be fine, I guess, but the main rules for the styling should be centralized in an unique place.

Step-by-step reproduction instructions

N/A

Screenshots, screen recording, code snippet

No response

Environment info

No response

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

@afercia afercia added [Type] Enhancement A suggestion for improvement. [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Editor /packages/editor [Feature] Show button text labels A preference in the Post and Site Editor that makes buttons show text instead of icons labels May 17, 2024
@afercia
Copy link
Contributor Author

afercia commented May 17, 2024

Here's the occurrences of the CSS selector .show-icon-labels I was able to find. At the time of writing there's several occurrences in 12 different files.

'Unlock' button in block toolbar 
https://github.com/WordPress/gutenberg/blob/2e439917b871eac2219b90c176ff4618c6e0852a/packages/block-editor/src/components/block-lock/style.scss#L62

Patterns explorer pagination:
https://github.com/WordPress/gutenberg/blob/2e439917b871eac2219b90c176ff4618c6e0852a/packages/block-editor/src/components/block-patterns-paging/style.scss#L25

Block switcher: small fix to prevent double label text 
https://github.com/WordPress/gutenberg/blob/2e439917b871eac2219b90c176ff4618c6e0852a/packages/block-editor/src/components/block-switcher/style.scss#L33

All buttons in the block toolbar, with padding override to 6px 
https://github.com/WordPress/gutenberg/blob/2e439917b871eac2219b90c176ff4618c6e0852a/packages/block-editor/src/components/block-toolbar/style.scss#L162

Block tools: 3 occurrences at line 198, 239, 247
various adjustments for block toolbar when the block has a parent
adjustments for block mover buttons
https://github.com/WordPress/gutenberg/blob/trunk/packages/block-editor/src/components/block-tools/style.scss

Block Inspector tabs 
https://github.com/WordPress/gutenberg/blob/2e439917b871eac2219b90c176ff4618c6e0852a/packages/block-editor/src/components/inspector-controls-tabs/style.scss#L1

LinkControl buttons 
https://github.com/WordPress/gutenberg/blob/2e439917b871eac2219b90c176ff4618c6e0852a/packages/block-editor/src/components/link-control/style.scss#L25

Inline format toolbar 
To my understanding, the inline format toolbar was removed in https://github.com/WordPress/gutenberg/pull/58945
Cc @youknowriad 
https://github.com/WordPress/gutenberg/blob/f25f59d8680b0c4d9b68d1f3aaa94e209f3b9b80/packages/block-editor/src/components/rich-text/style.scss#L33

Override for Post editor 'view posts' logo link in the toolbar when a site icon is set
https://github.com/WordPress/gutenberg/blob/f25f59d8680b0c4d9b68d1f3aaa94e209f3b9b80/packages/edit-post/src/components/header/style.scss#L4

Global styles panel header buttons
note: layout is currently broken 
https://github.com/WordPress/gutenberg/blob/72612dc94ce38ab2419669b3f0e844e515c975d1/packages/edit-site/src/components/global-styles-sidebar/style.scss#L83

Small adjustments fo the Inserter toggle button in the top bar 
Note: it seems some CSS properties are unnecessary 
Left amrgin adjustment for all Document tools buttons
https://github.com/WordPress/gutenberg/blob/72612dc94ce38ab2419669b3f0e844e515c975d1/packages/editor/src/components/document-tools/style.scss#L82

Editor header: 4 occurrences 
buttons in the editor top bar 
block mover when 'Top toolbar' is enabled 
pinned items - this should be checked, not sure the element 'interface-pinned-items' has also a 'show-icon-labels' CSS class
https://github.com/WordPress/gutenberg/blob/72612dc94ce38ab2419669b3f0e844e515c975d1/packages/editor/src/components/header/style.scss

@afercia afercia self-assigned this May 17, 2024
@cbirdsong
Copy link

Excited to see this! I’ve always wanted that setting to work more like MacOS toolbars.

@afercia
Copy link
Contributor Author

afercia commented May 20, 2024

The more I investigate this issue, the more I tend to think any CSS implementation is inherently fragile and not solid enough to make this feature reliable. Also, it's not well testable.

The current implementation uses a CSS pseudo element ::before or ::after depending whether one of the two is already used for other purposes. There are also edge cases, for example the inspector tabs, where the focus and active styles already use both ::before and ::after so that when 'Show button text labels' is enabled, the revealed text is slightly mis-positioned.

Screenshot 2024-05-20 at 14 54 16

Other potential issues may arise from other potential CSS conflicts.

Fudnamentally, revealing the text by using CSS pseudo elements that target the button aria-label attribute might seem a smart idea at first but it's a fragile CSS hack. This feature should use a more solid implementation.

However, I do realize the base Button component should not support this as a built-in feature. I can think of two options and I'd greatly appreciate some feedback from the Components package maintainers and other Gutenberg specialists:

  • Make the Button component support soem kind of generic transformation based on the environment the Button is used that is not specifically tied to 'Show button text labels'. As in: the environment may send in some way some props to the Button to instruct it to change in some way. This sounds a little against best practices though.
  • Keep the Button component 'pure' and introduce a new 'preference-aware' button in the Editor component. This coomponent would basically be a wrapper of the base Button that is aware of the user preference and just passes the right props to not render the SVG icons and render text instead.

The second option seems cleaner ot me and wouldn't require any CSS hacks.
Cc @WordPress/gutenberg-core @WordPress/gutenberg-components

@t-hamano
Copy link
Contributor

#46025 proposed not relying on global class names.

One approach I can think of is to change the behavior of the Button component ad hoc depending on whether this setting is enabled or not, without relying on the .show-icon-label class. That is, if this setting is enabled, it will render the actual text as a child instead of the icon:

function ParentComponent() {
	const showIconLabels = useSelect( ( select ) => {
		return select( preferencesStore ).get( 'core', 'showIconLabels' );
	}, [] );
	return (
		<>
			<ChildConponentOne showIconLabels={ showIconLabels } />
			<ChildConponentTwo showIconLabels={ showIconLabels } />
		</>
	);
}

function ChildConponentOne( { showIconLabels } ) {
	return (
		<Button
			label={ __( 'Push Me' ) }
			icon={ showIconLabels ? someIcon : undefined }
			showTooltip={ ! showIconLabels }
		>
			{ showIconLabels && __( 'Push Me' ) }
		</Button>
	);
}

function ChildConponenTwo( { showIconLabels } ) {
	return (
		<Button
			label={ __( 'Push Me' ) }
			icon={ showIconLabels ? someIcon : undefined }
			showTooltip={ ! showIconLabels }
		>
			{ showIconLabels && __( 'Push Me' ) }
		</Button>
	);
}

However, this will require changes to all UI that currently depend on the .show-icon-label class.

@mirka
Copy link
Member

mirka commented May 20, 2024

  • Make the Button component support soem kind of generic transformation based on the environment the Button is used that is not specifically tied to 'Show button text labels'. As in: the environment may send in some way some props to the Button to instruct it to change in some way. This sounds a little against best practices though.

We can accomplish this using the Context System. For what it's worth, I'm not against this approach at all. On the other hand, the latter approach with the Editor-only wrapper seems unfeasible because we'd have to replace all relevant Buttons in the Editor, some of which are already enclosed within a compound component.

I think the most difficult part would be the reliability of the automatic transform. Because Button unfortunately has a bunch of props, allowing consumers to set icons/text in different ways.

@afercia
Copy link
Contributor Author

afercia commented May 21, 2024

I think the most difficult part would be the reliability of the automatic transform. Because Button unfortunately has a bunch of props, allowing consumers to set icons/text in different ways.

Yes I have the same concern as well. For this reason I'd tend to think the base component should be kept unchanged. The wrapper component option seems more reasnbale to me as it addresses a feature that is specific to the Gutenberg editor.

we'd have to replace all relevant Buttons in the Editor, some of which are already enclosed within a compound component.

Yes. I'm not sure it's a lot of files to touch, actually I have the impression it's a few files overall. Some of these compound component already use an as prop that would allow to just replace the Button component with the 'ButtonWrapper'. As per the impact, I'd think we'd have to try it to have a more clear picture.
Also important: the 'ButtonWrapper' could have test to catch any issue when the base Button component changes in any way.

I'll try and submit a Draft PR so to have some proof of contept to look at.

@github-actions github-actions bot added the [Status] In Progress Tracking issues with work in progress label May 21, 2024
@afercia
Copy link
Contributor Author

afercia commented May 24, 2024

I just reported a new regression for this preference, which proves once more the current implementation is fragile. On latest trunk the Inspector tabs text is no longer visible. See #61947

@afercia
Copy link
Contributor Author

afercia commented May 27, 2024

#61947 / #61949 is a good example of how the current implementation is fragile and prone to break when some controls styling is changed without appropriately testing the consequences of those changes.

To me, such regressions prove a few things:

  • The process should be improved. Either contributors should know all the editor features that need to be tested or the process itself should make sure these features get actually tested before merging changes. Making sure both things are improved would be ideal.
  • Custom styling of base components with ad-hoc CSS should be avoided. When a new styling is desired, even if it's just s CSS animation, it would be way better to add a variant of the base component so that it is testable in the base component.
  • The implementation of the 'Show button text labels' feature should be changed and made testable.

@DaniGuardiola
Copy link
Contributor

@afercia agree on all counts. I believe @mirka created (or at least at some point showed me) some sort of decision workflow related to whether certain styles or features should be built into components vs. implemented at higher layers through escape hatches or overrides. Can we get that linked here?

@afercia
Copy link
Contributor Author

afercia commented May 27, 2024

Yes it would be great to have a look at that decision tree. I would say that, since this is a collaborative open source project, such a decision tree should be documented.

Regarding 'escape hatches or overrides', in general, based on my experience, proliferation of ad-hoc 'local' styling leads to UI inconsistencies and higher maintenance cost in the long run. This is typical in WordPress core, as it 'accumulated' a couple decades of development. I would love to see Gutenberg not taking the same path.

I'd think the editor should be very very strict and avoid ad-hoc styling as much as possible. For example, if a Button gets some custom ad-hoc styling for some design purposes that is only decorative and only for one case then I'd think introducing such a customization isn't worth it. On the other hand, when some custom styling proves to be beneficial and has multiple use cases, then it probably worths a variant to be added to the base component.

IMHO, a good example of what not to do si the cystom styling for the featured image buttons in the Post tab of the Inspector:

Screenshot 2024-05-27 at 15 28 14

As far as I can tell, that's a unique styling and it's not used anywhere else in the UI. To me, it just introduces inconsistency and doesn't add great value. Design should avoid to introduce such unique customizations.

@mirka
Copy link
Member

mirka commented May 27, 2024

I believe @mirka created (or at least at some point showed me) some sort of decision workflow related to whether certain styles or features should be built into components vs. implemented at higher layers through escape hatches or overrides. Can we get that linked here?

I'm sorry but I have no idea what you're referring to 🫣 Maybe I was talking about the general principle that @wordpress/components should be pure in the sense that they have no dependencies on Block Editor APIs or wp-admin stylesheets?

Either contributors should know all the editor features that need to be tested or the process itself should make sure these features get actually tested before merging changes. Making sure both things are improved would be ideal.

To be fair, I can't remember a time when @ciampo or I ever tested for "Show button text labels", nor had it been escalated to us as a QA issue. I was passively aware of the feature, but it was never in our smoke testing routine. From the maintainability standpoint, I think we need to improve the "Show button text labels" implementation to either be:

  1. An official @wordpress/components feature that is available to all consumers, and is easily testable in Storybook.
  2. A Block Editor feature that @wordpress/components has no responsibility for. (Devs making changes to @wordpress/components should not have to test for "Show button text labels" breakage at all.)

Given that "Show button text labels" breakage in a practical sense can also be dependent on the surrounding UI context, I think the latter would be ideal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Show button text labels A preference in the Post and Site Editor that makes buttons show text instead of icons [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). [Package] Editor /packages/editor [Status] In Progress Tracking issues with work in progress [Type] Enhancement A suggestion for improvement.
Projects
None yet
5 participants