Skip to content

[6.x] StatusIndicator conveys publish status by colour alone with no accessible name #15412

Description

@bpmore

Bug description

ui/StatusIndicator.vue can render as a bare coloured dot with no text and no accessible name. Where it does, publish status is conveyed by colour alone.

https://github.com/statamic/cms/blob/v6.31.0/resources/js/components/ui/StatusIndicator.vue#L41-L44

<span class="flex items-center gap-2">
    <span v-if="showDot" class="size-2 rounded-full" :class="statusClass" v-tooltip="label" />
    <span v-if="showLabel" class="status-index-field select-none" :class="`status-${status}`" v-text="label" />
</span>

When showLabel is false — which is how the entry editor header renders it — the only cue is the colour:

{ "cls": "size-2 rounded-full bg-green-400",
  "title": null, "ariaLabel": null, "srOnlySibling": null,
  "bg": "oklch(0.792 0.209 151.711)" }

Four statuses map to four colours (published, scheduled, expired, draft) with no shape, text or icon difference between them.

  • SC 1.4.1 Use of Color (A) — colour is the only visual means of conveying the status.
  • SC 1.1.1 Non-text Content (A) / SC 4.1.2 (A) — the span has no aria-label, no title, no sr-only text, so its accessible name is empty. A screen reader user gets nothing at all.

The listing tables are fine, because they render with showLabel and the word "Published" is present. The failure is specific to the dot-only usage.

The tooltip is not a sufficient alternative

v-tooltip="label" is attached, so a sighted mouse user can hover the dot and read the status. That does not satisfy either criterion:

  • the span is not focusable, so keyboard users cannot reach it
  • touch users cannot hover
  • the tooltip provides no accessible name to assistive technology
  • and the tooltip itself fails SC 1.4.13 — see the companion issue I'm filing alongside this

How to reproduce

  1. composer create-project statamic/statamic, create a collection with a published entry
  2. Open the entry for editing
  3. Inspect the small coloured dot beside the title:
const dot = document.querySelector('.size-2.rounded-full');
dot.getAttribute('aria-label');  // null
dot.getAttribute('title');       // null
dot.textContent;                 // ""

Suggested fix

Add an sr-only span carrying label next to the dot whenever showLabel is false, so the status has a text equivalent regardless of input method:

<span v-if="showDot" class="size-2 rounded-full" :class="statusClass" v-tooltip="label" />
<span v-if="showDot && !showLabel" class="sr-only" v-text="label" />

That satisfies 1.1.1 and 4.1.2. For 1.4.1, a sighted user still has only colour, so pairing the dot with a shape or icon per status would be the fuller fix — though the sr-only text plus the visible title context may be judged sufficient depending on how strictly you read it.

Environment

Environment
Laravel Version: 13.30.1
PHP Version: 8.4.23
Composer Version: 2.10.2
Environment: local
Debug Mode: ENABLED
Maintenance Mode: OFF
Timezone: UTC
Locale: en

Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED

Drivers
Broadcasting: log
Cache: file
Database: sqlite
Logs: stack / single
Mail: log
Queue: sync
Session: file

Storage
public/storage: NOT LINKED

Statamic
Addons: 0
License Key: Not set
Sites: 1
Stache Watcher: Enabled (auto)
Static Caching: Disabled
Version: 6.31.0 PRO

Installation

Fresh statamic/statamic site via CLI

Additional details

Found during a WCAG 2.1 AA audit of a vanilla composer create-project statamic/statamic install with no addons and no custom code. Tested with axe-core 4.x on Chromium 153 at 1440x1000, plus manual keyboard traversal. Source references point at v6.31.0.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions