Skip to content

A11y Addons control panel - #6345

Open
deodorhunter wants to merge 50 commits into
mainfrom
5142-a11y---site-setup---addon-ons---cms-ui
Open

A11y Addons control panel #6345
deodorhunter wants to merge 50 commits into
mainfrom
5142-a11y---site-setup---addon-ons---cms-ui

Conversation

@deodorhunter

@deodorhunter deodorhunter commented Sep 27, 2024

Copy link
Copy Markdown
Contributor

This PR overhauls current Addons Control panel UI using react-aria-components and solves #5142.
All accordions removed, UI is now akin to Plone Classic.
Aria pattern used: ARIA grid pattern through GridList component

Changelog:

  • Written in Typescript leveraging @plone/types
  • Component UI overhauled and code splitted, really minor changes to existing logic (types mostly)
  • Updated tests and added new tests and related mocks/fixtures/snapshots for Cypress and Jest/Testing Library.
  • Updated some Addons related types in @plone/types package
  • Added stylesheet and imported it directly in the component, css splitting and lazy loading works as expected. Will move styles in less theme files if deemed better/necessary
  • Translations

UI Preview

image
image

@deodorhunter deodorhunter self-assigned this Sep 27, 2024
@deodorhunter deodorhunter linked an issue Sep 27, 2024 that may be closed by this pull request
@netlify

netlify Bot commented Sep 27, 2024

Copy link
Copy Markdown

Deploy Preview for plone-components canceled.

Name Link
🔨 Latest commit ef27f80
🔍 Latest deploy log https://app.netlify.com/sites/plone-components/deploys/67ea8f15ac350e0008ad75ab

Comment thread packages/volto/src/components/manage/Controlpanels/Addons/index.css Outdated
@deodorhunter

Copy link
Copy Markdown
Contributor Author

Update
This pr is now complete with all missing translations in all supported languages. Got some help from our well known GPT buddy, as I would have hated leaving blanks for other languages.
Haven't seen strange/unusual translations during a quick cross check with Translate and Deepl, but you never know...

@ichim-david
ichim-david requested a review from Wagner3UB October 1, 2024 09:19
@ichim-david
ichim-david requested a review from sneridagh October 29, 2024 12:00
@ichim-david

Copy link
Copy Markdown
Member

@pnicolli @sneridagh I've looked at the bundle implication of loading react-aria-components.
It seems that it's not bundled in the default bundle and only used on the addons
react-aria-addons-component
I wonder it react-aria doesn't have better imports to avoid loading the entire library if you only use a couple of components.
Given the fact that we don't load it in the default bundle I'm not against this although I find it a bit strange that we have a dependency on react-aria-components within plone.components and now we load it also in volto core directly.
Whatever you guys decide I'm fine given that we don't fatten the default bundle :).

@pnicolli

Copy link
Copy Markdown
Contributor

@ichim-david yeah Victor and I discussed this briefly with the people doing stuff with react-aria-components during Salamina Sprint and we said that we wouldn't use plone/components here because it's still alpha and kind of wip officially, but we can use react-aria-components for now, since moving from this to plone/components should remain easy enough.
Regarding a more precise import, we will need to look into it while working on plone/components so I think it's safe to say it's not a big problemi for now.

@JeffersonBledsoe

JeffersonBledsoe commented May 8, 2025

Copy link
Copy Markdown
Member

@pnicolli Thanks for the re-ping for the accessibility team. I'll take a review next week and follow up with the others!

Edit: I've not had time to look at this, I'll take a look within the next few weeks (June).

@davisagli davisagli modified the milestones: 19.x.x, 20.x.x May 18, 2026
@Wagner3UB

Copy link
Copy Markdown
Contributor

@deodorhunter an you give me an update on this PR, please? Do you think it can be finished, or at least merged with some improvements? Thank you!

@deodorhunter

Copy link
Copy Markdown
Contributor Author

@deodorhunter an you give me an update on this PR, please? Do you think it can be finished, or at least merged with some improvements? Thank you!

Hi @Wagner3UB!
So, PR was complete and potentially ready to be merged with fixes from previous reviews implemented a long time ago. Sadly, we are looking at a 1+ year drift on this, my brain no longer has a working memory of the domain/scope.
Aside from some tedious merge conflicts solving as shown by GitHub (last time I worked on Volto was v18), could you be more specific on what kind of improvements would we need on this one? Did you test it accessibility wise and found some issue?
IIRC this was built on a much earlier version of React Aria Components, we should also probably check if improvements or breaking changes were made to the lib and components themselves during the hiatus.
If I have a clear, defined scope of what needs changes/fixes/improvements I can take a look at this in the coming weeks :)

@pnicolli

Copy link
Copy Markdown
Contributor

@Wagner3UB I remember that this was indeed finished and just needed a review from the a11y team which was postponed but it makes sense to review and merge this now that the team regained momentum and energy. I would recommend solving the conflicts and reviewing as-is, I don't think it needs functional changes (unless it has a11y bugs ofc)

@Wagner3UB

Copy link
Copy Markdown
Contributor

Great! Thanks for the clarification @deodorhunter and @pnicolli.

I didn’t go beyond reading the whole discussion yet, but based on your feedback, we can definitely move forward. I’m also happy to hear that it is already finished.

Marty, no worries, I can handle the conflict resolution myself. I’m a bit more familiar with the current context and should be able to do it more quickly. I’ll also run some tests and then ask the a11y team members to take a general look at it.

Thanks!

# Conflicts:
#	packages/volto/locales/ca/LC_MESSAGES/volto.po
#	packages/volto/locales/de/LC_MESSAGES/volto.po
#	packages/volto/locales/en/LC_MESSAGES/volto.po
#	packages/volto/locales/es/LC_MESSAGES/volto.po
#	packages/volto/locales/eu/LC_MESSAGES/volto.po
#	packages/volto/locales/fi/LC_MESSAGES/volto.po
#	packages/volto/locales/fr/LC_MESSAGES/volto.po
#	packages/volto/locales/hi/LC_MESSAGES/volto.po
#	packages/volto/locales/it/LC_MESSAGES/volto.po
#	packages/volto/locales/ja/LC_MESSAGES/volto.po
#	packages/volto/locales/nl/LC_MESSAGES/volto.po
#	packages/volto/locales/pt/LC_MESSAGES/volto.po
#	packages/volto/locales/pt_BR/LC_MESSAGES/volto.po
#	packages/volto/locales/ro/LC_MESSAGES/volto.po
#	packages/volto/locales/ru/LC_MESSAGES/volto.po
#	packages/volto/locales/volto.pot
#	packages/volto/locales/zh_CN/LC_MESSAGES/volto.po
#	packages/volto/package.json
#	packages/volto/src/components/manage/Controlpanels/Addons/AddonsControlpanel.test.jsx
#	packages/volto/src/components/manage/Controlpanels/AddonsControlpanel.jsx
#	packages/volto/src/components/manage/Controlpanels/__snapshots__/AddonsControlpanel.test.jsx.snap
#	pnpm-lock.yaml
…ntry

Translate the 7 new msgids introduced by the Addons control panel
refactor across all locales, and restore the "upgradeVersions" msgid
that was silently dropped from volto.pot during the merge from main,
which had cascaded into ca, eu and pt losing their existing translation.
…traction

The intl.formatMessage call referenced the 'upgradeVersions' id without
a defaultMessage, so the official pnpm i18n extraction silently dropped
it from volto.pot on every run, wiping the translation from all locales.
@Wagner3UB Wagner3UB self-assigned this Jul 29, 2026
@Wagner3UB

Copy link
Copy Markdown
Contributor

@deodorhunter @pnicolli

I went through the merge conflicts, standardizing some files in the process, but kept the original structure and intent intact. I also updated a few dependency versions that were out of sync, since main had moved on quite a bit since this branch was last rebased.

While testing the merged result, I found and fixed a few accessibility issues:

  • Install/uninstall/update was unreachable by keyboard (pre-existing). Every row had isDisabled set unconditionally, left over from an earlier design where the row itself triggered the action, before it was reworked to use a dedicated button. With isDisabled set, Tab and Enter/Space did nothing, only a mouse click worked. Removed isDisabled and wired onAction on each row, so Enter/Space now triggers the same action as the button.
  • The "update" label was reading raw placeholders (pre-existing). The upgradeVersions message had no defaultMessage, so pnpm i18n silently dropped it from every locale file. The button's aria-label read literally "Update from version {origin} to {destination}" instead of real version numbers. Fixed by declaring the message properly and passing the actual values.
  • The add-ons list rendered as a tiny scrollable box instead of filling the section (caused by the merge). @plone/components, a dependency that only exists on main, ships a generic base style for .react-aria-GridList (width: 250px, max-height: 300px), meant for compact widgets like dropdowns. Since react-aria-components always applies that class name unless overridden, it leaked into our list once the branches merged. Fixed by giving each GridList its own className.
  • main also brought in a conflicting react-router version, which broke build:types in CI with an ambiguous RouteComponentProps type. Fixed by typing the one prop actually used (location.pathname) directly instead of relying on that import.

Examples:
First item list:
first-item-list

Second item list:
second-item-list

@Wagner3UB

Copy link
Copy Markdown
Contributor

One thing I want to flag for discussion. The component is built on a GridList (which comes with role="grid", i.e. rows and columns), but in practice the layout is always a single column with several rows, and that's not going to change. For someone using a screen reader, this makes the widget announce itself as a full 2D table ("table, 1 column, N rows", plus the "press Control-Option-Shift-Down to enter this table" prompt), way more complexity than the content actually has. It's not a table, it's a list of buttons, each tied to one action: install or uninstall.

What I'd expect instead: a labeled container per section ("Updates available: 0", "Available add-ons: 6", "Installed add-ons: 3"), and inside it a plain list of buttons, each with its own clear label. If some structure is still needed, Enter could get you into the container and Tab could move between items, without the table semantics on top. This would likely mean switching from GridList to ListBox (both from react-aria-components), which I didn't do here since it touches more of the component's structure and felt like a bigger call to make unilaterally. Happy to take it on if the team agrees it's the right direction.

cc:/ @deodorhunter @pnicolli @wesleybl @Humanaice

@Wagner3UB
Wagner3UB requested review from Humanaice and wesleybl and removed request for ichim-david and sneridagh July 29, 2026 10:06
@Wagner3UB

Copy link
Copy Markdown
Contributor

Quick follow-up on the open points above:

  • Double-click: verified, it doesn't trigger an install/uninstall on its own. A single click does its job once, and I couldn't get an extra call out of it even forcing a double-click event directly.
  • Narrow viewports (320px and below): tested down to 301px, the layout holds up fine. Title wraps to a second line when needed and the button stays put, no overlap.
  • GridList vs ListBox: leaving this as GridList for now, per the discussion above. Not blocking this PR.

@Wagner3UB Wagner3UB removed their assignment Jul 29, 2026
@stevepiercy
stevepiercy requested a review from ichim-david July 30, 2026 20:07

@stevepiercy stevepiercy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The id Add Addons doesn't have a matching msgid. Also its defaultMessage is incomplete.

addAddons: {
id: 'Add Addons',
defaultMessage:
'To make new add-ons show up here, add them to your configuration, build, and restart the server process. For detailed instructions see',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

see... what?

</h2>
<FormattedMessage
id="Add Addons"
defaultMessage="To make new add-ons show up here, add them to your configuration, build, and restart the server process. For detailed instructions see"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

see... what?

Comment on lines +2600 to +2602
#. Default: "No installed add-ons."
#: components/manage/Controlpanels/Addons/AddonsControlpanel
msgid "No installed add-ons available"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Between the two, I'm not sure which is more correct, so I'll change both so they match each other.

Suggested change
#. Default: "No installed add-ons."
#: components/manage/Controlpanels/Addons/AddonsControlpanel
msgid "No installed add-ons available"
#. Default: "No installed add-ons available."
#: components/manage/Controlpanels/Addons/AddonsControlpanel
msgid "No installed add-ons available."

Comment on lines +2961 to +2971
msgid "Press Enter to install this add-on"
msgstr ""

#. Default: "Press Enter to uninstall this add-on."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Press Enter to uninstall this add-on"
msgstr ""

#. Default: "Press Enter to update this add-on."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Press Enter to update this add-on"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nitpicky for consistency, but probably a good thing to do.

Suggested change
msgid "Press Enter to install this add-on"
msgstr ""
#. Default: "Press Enter to uninstall this add-on."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Press Enter to uninstall this add-on"
msgstr ""
#. Default: "Press Enter to update this add-on."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Press Enter to update this add-on"
msgid "Press Enter to install this add-on."
msgstr ""
#. Default: "Press Enter to uninstall this add-on."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Press Enter to uninstall this add-on."
msgstr ""
#. Default: "Press Enter to update this add-on."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Press Enter to update this add-on."

@@ -4386,6 +4431,11 @@ msgstr ""
msgid "Uploading image"
msgstr ""

#. Default: "Use the arrows to move between items."
#: components/manage/Controlpanels/Addons/AddonItem
msgid "Use the arrows to move between items"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Another nitpick.

Suggested change
msgid "Use the arrows to move between items"
msgid "Use the arrows to move between items."

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

Projects

Status: Plan approved

Development

Successfully merging this pull request may close these issues.

a11y - site setup - Addon-ons - cms ui

7 participants