cms icon indicating copy to clipboard operation
cms copied to clipboard

Collapsible source headings

Open brianjhanson opened this issue 6 months ago • 8 comments

Description

Adds a "collapsible" option to source headings when customizing.

CleanShot 2025-05-06 at 13 34 21@2x

When checked, headings will get an icon before the label and items beneath the heading can be collapsed.

If the current page is an ancestor of a collapsed section, the icon will flip colors to denote a collapsed item is active.

CleanShot 2025-05-06 at 13 36 53@2x

The state of each toggle will be stored in cookies so it will persist across page loads. The only downside is a minor flash of the expanded state.

Related issues

Fixes CMS-1339

brianjhanson avatar May 06 '25 18:05 brianjhanson

Related issues: https://github.com/craftcms/cms/discussions/13307#discussioncomment-8544658 https://github.com/craftcms/cms/discussions/11340 https://github.com/craftcms/cms/discussions/16065

brianjhanson avatar May 06 '25 18:05 brianjhanson

The setting seems unnecessary? From an AX perspective it would be weird if some headings are collapsible and some aren’t.

Updated, all headings are just collapsible now.

I don’t love the collapsed toggle styling’s inverted colors. Let’s just have it look the same, but upside-down, as when the heading is expanded.

The toggle will only appear this way when one of the items nested beneath it (and therefore invisible when collapsed) is selected. The goal was to provide some kind of "hey a thing under here is selected" indicator. We could also highlight the actual item that's collapsed, but that felt a little too strong to me.

I also remove these lines because a heading will always get a key now but let me know if you'd rather minimize the changes and totally remove the key for headings. I think they could be useful if we want to add settings to a heading in the future, but that might be a big if. Now that all headings are collapsible they don't necessarily need a key.

brianjhanson avatar May 08 '25 15:05 brianjhanson

Thanks @gcamacho079! 🙌

The disclosure controls should be updated to either be at least 24px in size, or have sufficient space with adjacent links

I think we have enough space here (but please correct me if I'm wrong).

I found this guidance:

it must be possible to draw a virtual circle centered on the target with a diameter of 24 pixels that does not intersect any other targets, nor any of the circles on other undersized targets.

So I whipped up some CSS to see and I think things look good?

CleanShot 2025-05-14 at 08 37 17@2x

The disclosure control should also include the heading name for extra context, either as visually-hidden text, or referenced via aria-labelledby or aria-describedby. The benefit of using visually-hidden text or aria-labelledby would be that the control is more accessible to voice control users, and screen reader users who may be navigating controls out of context.

Fixed in https://github.com/craftcms/cms/pull/17226/commits/702eda4323b916e85efadd9edd2b6ebb7e09e25c happy to tweak that language though. I'd love a recommendation.

This issue already exists, but I’m wondering if we should require headings not be blank, as it’s a bit disconcerting when there’s a disclosure toggle next to a blank heading.

As of https://github.com/craftcms/cms/pull/17226/commits/d5316e7add2944a253db500b2de1f1914ad4e7d6 blank headings won't be collapsible. I feel like that's probably the best compromise for the moment.

The inverted button communicates to sighted users that one of the child items is active, but that information isn’t communicated to screen reader users. It may be helpful to add something like aria-current="true" to communicate that we’re currently inside that nested source menu. 🤔

Would aria-current=true be expected on the parent any time the parent has an active child? Or only when the parent is collapsed (as with the indicator). I'm assuming only when it is collapsed, but just wanted to clarify.

brianjhanson avatar May 14 '25 14:05 brianjhanson

I think we have enough space here (but please correct me if I'm wrong).

@brianjhanson I think this only applies when the disclosure is open; the safe clickable area of the disclosure toggle is 21.2px according to the testing extension, due to the first link in the nested source menu:

Outlines drawn around the disclosure toggle and the source menu underneath

Would aria-current=true be expected on the parent any time the parent has an active child? Or only when the parent is collapsed (as with the indicator). I'm assuming only when it is collapsed, but just wanted to clarify.

The reason I flagged it is because there’s a visual indicator that there’s an active child without there being an equivalent for AT users. When the disclosure is expanded, there isn’t an indicator on the parent, in which case, there’s no hard requirement to include that information for AT users.

We can include it, though, for clarity, and I realized after my initial comment that we can actually put the aria-current attribute on the li itself, rather than it needing to just be on an interactive element (i.e., the disclosure button).

gcamacho079 avatar May 14 '25 15:05 gcamacho079

Thanks @gcamacho079!

I just added a bit more margin to headings which gets the hit target test to pass in AXE for me.

We can include it, though, for clarity, and I realized after my initial comment that we can actually put the aria-current attribute on the li itself, rather than it needing to just be on an interactive element (i.e., the disclosure button).

Just updated so the parent li will get aria-current=true when a descendent is selected and the ancestor is collapsed.

brianjhanson avatar May 14 '25 20:05 brianjhanson

If the current page is an ancestor of a collapsed section, the icon will flip colors to denote a collapsed item is active.

Not sure I love this… it’s not very clear why one of the toggles has a different style at first.

Couple alternative options:

  • The group with the selected source could just not be collapsible
  • We could always show the selected source, regardless of whether its group is collapsed – like Discord:
a collapsed channel group in Discord, showing the #general channel below it anyway, since it’s selected

brandonkelly avatar Jun 08 '25 01:06 brandonkelly

I decided to go with the Discord style approach.

https://github.com/user-attachments/assets/1e7e75cc-219b-44ae-af69-6873ce8c975a

brianjhanson avatar Jun 16 '25 15:06 brianjhanson

Doing some testing on the 5.8 branch and noticed a bug that I think might be related to the changes in this PR:

On a multi-site build, all headings are now visible for all sites, even if they have no sources in the currently requested site.

English site (has all sections): CleanShot 2025-06-26 at 22 14 06

Swedish site (only has the "Blog" section, but the "Content" heading still appears): CleanShot 2025-06-26 at 22 16 29

mmikkel avatar Jun 26 '25 20:06 mmikkel

I'm also not crazy about how this feature works with nested sources 😅

In the screenshots below, I've added some nested sources to the News source. IMO, the heading and the News source both having identical expand toggles on the same level looks... a little bit confusing (especially when the nested source is collapsed)?

CleanShot 2025-06-26 at 22 25 57

CleanShot 2025-06-26 at 22 23 58

There's also a bug when the heading is collapsed, where the toggle for the "News" source beneath it is still visible:

CleanShot 2025-06-26 at 22 26 45

The setting seems unnecessary? From an AX perspective it would be weird if some headings are collapsible and some aren’t.

Respectfully disagree 😌 For sites with only a few sources, or for headings with only 1 or 2 sources beneath them, being able to expand/collapse the headings is arguably pretty pointless and mostly feel like UI noise. I get the general argument about consistent UI, and this is a very cool feature, but in terms of AX I think this is one of those things that makes most sense to have as an opt-in thing for the situations where it is genuinely useful. (Also, if it was optional I could just... not enable it for any headings with nested sources beneath them, considering the caveats above 😇)

I don't think authors will have a problem with some headings being collapsible, and others not, assuming devs enable it for the headings where it makes sense, and where it feels like an intuitive and useful behaviour to have.

mmikkel avatar Jun 26 '25 20:06 mmikkel