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

Implement KLiveRegion and useKLiveRegion #668

Closed
MisRob opened this issue Jun 20, 2024 · 2 comments · Fixed by #687
Closed

Implement KLiveRegion and useKLiveRegion #668

MisRob opened this issue Jun 20, 2024 · 2 comments · Fixed by #687
Assignees
Labels
category: library Shared code library

Comments

@MisRob
Copy link
Member

MisRob commented Jun 20, 2024

Summary

This is a proposal for a new component and an accompanying composable, <KLiveRegion> and useKLiveRegion.

<KLiveRegion> will render itself as two live regions, one with a status role and another with an alert role:

<div role="status">
  {{ statusMessage }}
</div>

<div role="alert">
  {{ alertMessage }}
</div>

A single <KLiveRegion> is supposed to be used in an app and high in the app's structure.

useKLiveRegion can be imported to multiple places in an app that can send status or alert messages to <KLiveRegion> via useKLiveRegion.sendStatusMessage(<string>) or useKLiveRegion.sendAlertMessage(<string>).

The documentation will contain brief guidance with relevant references guiding developers on when to use or not use live regions, and what types of information should be sent as status messages and what should be alert messages.

Background

Originally motivated by the ongoing sortable table work. Upon discussing with @radinamatic, it seems that the table will need to utilize live region in some use-cases, particularly to communicate loading/loaded states when re-fetching data when sorting is done on the backend. However, the table itself shouldn’t contain the live region as this would only add another live region to the already many regions in Kolibri. Additionally, a Kolibri audit revealed we use many live regions and we wrap whole components in them, which can lead to a number of problems.

The Value Add

  • Encapsulates commonly re-used logic
  • By design enforces best practices that prevent messages from getting lost, conflicting with each other, or from irrelevant and confusing information being announced. Such problems are often caused by:
    • multiple live regions
    • live region loaded into the DOM too late
    • wrapping rich HTML content by live region
    • wrapping interactive content by live region
  • Possible integration with some KDS components that could send messages to the live region by default (to be decided, see the discussion below)

Possible Tradeoffs

  • Not aware of any

Related

Resources

@MisRob MisRob added type: proposal New feature or request TODO: needs decisions Further discussion and planning necessary labels Jun 20, 2024
@MisRob
Copy link
Member Author

MisRob commented Jun 20, 2024

To decide/discuss

(1) aria-live vs role

Would it be better if <KLiveRegion> rendered itself as

<div aria-live="polite">
  {{ politeMessage }}
</div>

<div aria-live="assertive">
  {{ assertiveMessage }}
</div>

rather than using the aforementioned roles?

  • The roles add semantic meaning and can enhance some screen readers. For example, role=alert prepends announcements with “Alert: …”, whereas aria-live doesn’t do that.
  • There seems to be a tension between semantics and universality. Roles provide better semantics that, on the other hand, may not be suitable for such a general component. For example, not all polite messages may not necessarily represent status messages.

(2) Internal integration of KDS components with the live region

I imagine that useKLiveRegion could be in some cases internally integrated with relevant KDS components. However, this approach's main advantage seems to also be its main drawback. For example, consider a table component that internally sends announcements about loading/finished loading to the live region. For this purpose, it receives the region’s ID and translated announcement strings.

  • Pros:
    • Eliminates the need to write guidance on what should and should not be announced from the table
    • Enforces some parts of a11y without any extra steps needed
    • Simple default behavior, no need to re-implement sending same announcements at multiple app places
  • Cons:
    • The table needs to be fed by more data
    • Some announcements are hidden from developers' eyes. This risks sending duplicate messages unintentionally (consider the situation we’d decide to show snackbars for loading state in Kolibri where all snackbars updates are currently announced)

I can think of mitigating some of the cons of both approaches to at least some extent technically as well as by documentation but for now, I’d be particularly grateful for higher-level feedback on whether introducing such approach would be an interesting pattern in KDS, or not.

@MisRob
Copy link
Member Author

MisRob commented Jul 10, 2024

Discussed with the team, so moving from the proposal stage.

Decisions:

  • Use aria-live rather than role. Reason: General component.
  • KDS components will integrate with the live region internally. Reason: Efficiency, robustness.
    • @rtibbles feedback: a component that wants to use live region it should throw warning if the live region is not available

@MisRob MisRob changed the title Proposal: Implement KLiveRegion and useKLiveRegion Implement KLiveRegion and useKLiveRegion Jul 10, 2024
@MisRob MisRob added category: library Shared code library and removed TODO: needs decisions Further discussion and planning necessary type: proposal New feature or request labels Jul 10, 2024
@MisRob MisRob mentioned this issue Jul 23, 2024
9 tasks
@marcellamaki marcellamaki added this to the KDS Priority Triage milestone Jul 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: library Shared code library
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants