sumup-oss / circuit-ui

SumUp's design system for the web
https://circuit.sumup.com
Apache License 2.0
923 stars 130 forks source link

Add side panel component #1354

Closed hris27 closed 2 years ago

hris27 commented 2 years ago

Visual

Screenshot 2022-01-10 at 14 33 06

For more details check out the component specs in Figma.

Context

The side panel component is an extra surface for contextual information that can support the screen's primary content. It appears only upon user interaction with another element on the primary page and can always be dismissed.

State

The side panel starts in the closed state and upon user interaction slides in from the right (desktop) or bottom (mobile). On desktop the side panel pushes and condenses the primary content and there is no overlay. Clicking the close button in the side panel header closes the panel in the opposite direction.

Multiple side panels can stack one over the other, e.g. when an interaction within the first side panel should open another one. In this case every panel but the first has a back arrow that closes only the corresponding panel. The close button closes the entire stack. Ideally there won't be more than two side panels rendered simultaneously. A secondary side panel opens from the right on both desktop and mobile.

When the side panel is opened the focus should move to it to facilitate keyboard navigation. Upon closing the side panel the focus should return to the previously focused element (if it still exists). While the side panel is opened the keyboard navigation is trapped within its boundaries.

Progressive enhancement

On screen resolutions of 768px and above the side panel slides in from the right/trailing side of the screen and pushes the main content. On screen resolutions below 768px the first side panel slides in from the bottom and the those stacking on top of it from the right, covering the primary content. The content within the panel has then a max width of 480px and is centred horizontally. The side panel's header is sticky and remains visible while the content is scrolled.

robinmetral commented 2 years ago

Thank you for opening this issue! Just a few thoughts:

The side panel starts in the closed state and upon user interaction slides in from the right (desktop) or bottom (mobile).

Would it not make sense to slide from the right even on mobile? This would be closer to the pattern in native apps. Unless we consider side panels to be closer to modals, which do tend to slide up (like Circuit modals on mobile). But I think that for things like detail views, it's more common to have a view slide in from the right.

When the side panel is opened the focus should move to it to facilitate keyboard navigation.

❤️

A few more questions:

hris27 commented 2 years ago

Would it not make sense to slide from the right even on mobile? This would be closer to the pattern in native apps. Unless we consider side panels to be closer to modals, which do tend to slide up (like Circuit modals on mobile). But I think that for things like detail views, it's more common to have a view slide in from the right.

I'm not sure why it was decided this way but the modal analogy seems spot on. On mobile the side panel will pretty much look like an immersive modal.

does focus go to the close button or to the entire panel? (I haven't done research on this pattern yet)

I haven't done any research on this either but I was thinking of moving the focus to the entire panel and not a specific element within it. In the case of a secondary side panel the back arrow button will come before the close button. Perhaps Caleb would be able to help us choose the best approach.

is focus trapped on the panel like in modals?

I guess on mobile it should since we cover the entire screen. Only the top-most panel should be focusable. On desktop I think we should be able to move focus back to the primary content since there is no overlay and the page should remain interactive.

robinmetral commented 2 years ago

Re: accessibility pattern for the side panel. I've looked into this on and off for the past couple of days and I'll share my learnings here 🎓

Panel a11y patterns

High level, I'm on the fence between ~three~ two patterns:

  1. (non-)modal dialog
  2. disclosure (show/hide)
  3. ~tabs~

Here's some details on each:

(Non-)modal dialog

In a nutshell: a non-modal dialog is like a modal, but doesn't prevent user interaction on the rest of the UI. An example (from the NN group article) is Gmail's "New Message" feature: the email editor overlays parts of the UI, but the rest of it isn't inert: the editor is non-modal.

Pros

Cons

Disclosure (show/hide)

The disclosure pattern at its simplest is the HTML <details> element. The aria equivalent (for better browser support) is a control element (role button) that toggles the visibility of another element and has aria-expanded set to true/false when details are visible/hidden. Adrian Roselli wrote about it.

Pros

Cons

~Tabs~

I wanted to mention tabs, because the pattern would probably suit our initial use case best, but it falls short because at least one tab needs to be active at any time. Designs for the panel make it dismissible. Also, the side panel could also be used in cases where there is only one control, and not a list of them.

Panels in other design systems

I've looked around for other similar patterns and their implementation, but unfortunately, while many design systems contain similar components (Carbon's Panels, Material's Sheets, Lightning's Panels), I couldn't find many explicit accessibility guidelines that we could use as inspiration.

Lightning's component docs have a few bullet points on accessibility, and we can deduce that the component is intended to be used as a disclosure pattern. However there's no mention of the component's behavior on mobile.

Closing thoughts

I'm tending towards using a modal dialog behavior here, essentially extending the obvious mobile pattern to desktop, and maintain consistency within the component. I feel that the way that it was design fits the dialog pattern much better (with the close button, etc.). The experience of mouse users on desktop would be slightly better as they'll be able to interact with the rest of the app while keeping the panel open.

Also: this would be a really nice pattern to actually test with AT users. I'll look into it and let you know!

Any concerns/other opinions here?

connor-baer commented 2 years ago

Thank you for the time and effort you’ve put into researching this, @robinmetral. It's deeply appreciated 🙇‍♂️

I agree with your suggestion that the non-dialog modal is the way to go. It sounds like the best option for users and the simplest to implement in Circuit UI.

hris27 commented 2 years ago

These are some great insights, @robinmetral. Thank you for doing such an extensive research 🙏

I too think that the non-modal dialog is the way to go.

I was looking at Google Calendar's event dialogs yesterday and they too have a similar disparity between mouse and keyboard navigation. They are non-modal but do utilize a focus trap.

robinmetral commented 2 years ago

Happy that we're on the same page! ❤️ Let's do it 🏗️