Files
metabuilder/qml/MetaBuilder/CMediaHeader.qml
johndoe6345789 d9ca84628b feat(a11y): deep keyboard accessibility pass across all QML components
Second-pass a11y work across all 12 component groups. Every interactive
element now has activeFocusOnTab, Keys.onReturnPressed/SpacePressed, and
context-aware Accessible.name/description bindings.

Highlights:
- Dialogs: keyboard handlers with enabled-guard on confirm buttons
- CDropdownMenu: full keyboard nav (Up/Down/Enter/Escape)
- CLoginForm: explicit KeyNavigation.tab chain (username→password→submit)
- CNotificationBell: dynamic "3 notifications"/"No notifications" name
- CJobProgressBar: Accessible.minimumValue/maximumValue/currentValue
- CExecutionStatusDot: "Execution status: Running/Passed/Failed" binding
- CKeyboardShortcuts: invisible Repeater exposes all shortcuts to a11y tree
- CDataTable rows: "Row N of M" descriptions
- Canvas elements: Accessible.Canvas role + keyboard zoom (+/- keys)
- DropdownExpandedList: focus-highlight extended to :activeFocus
- Dynamic names reflect loading state (e.g. "Signing in, please wait")

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 20:53:53 +00:00

94 lines
3.1 KiB
QML

import QtQuick
import QtQuick.Layouts
import QmlComponents 1.0
CCard {
id: root
objectName: "mediaHeader"
Accessible.role: Accessible.Pane
Accessible.name: "Media service header"
Layout.fillWidth: true
property string serviceStatus: "unknown"
property string serviceVersion: ""
property string lastHealthCheck: ""
property int jobCount: 0
property int radioCount: 0
property int tvCount: 0
property int pluginCount: 0
signal refreshClicked()
ColumnLayout {
anchors.fill: parent; anchors.margins: 20; spacing: 12
FlexRow {
Layout.fillWidth: true; spacing: 12
CText { variant: "h2"; text: "Media Service" }
CBadge { text: "God Panel" }
CStatusBadge {
status: root.serviceStatus === "online"
? "success"
: root.serviceStatus === "offline"
? "error" : "warning"
text: root.serviceStatus === "online"
? "Online"
: root.serviceStatus === "offline"
? "Offline" : "Checking..."
}
Item { Layout.fillWidth: true }
CButton {
text: "Refresh"
variant: "ghost"; size: "sm"
activeFocusOnTab: true
Accessible.role: Accessible.Button
Accessible.name: "Refresh media service"
Keys.onReturnPressed: root.refreshClicked()
Keys.onSpacePressed: root.refreshClicked()
onClicked: root.refreshClicked()
}
}
CDivider { Layout.fillWidth: true }
FlexRow {
Layout.fillWidth: true; spacing: 8
CChip {
text: root.jobCount + " Jobs"
Accessible.role: Accessible.StaticText
Accessible.name: root.jobCount + " Jobs"
}
CChip {
text: root.radioCount + " Radio Channels"
Accessible.role: Accessible.StaticText
Accessible.name: root.radioCount
+ " Radio Channels"
}
CChip {
text: root.tvCount + " TV Channels"
Accessible.role: Accessible.StaticText
Accessible.name: root.tvCount
+ " TV Channels"
}
CChip {
text: root.pluginCount + " Plugins"
Accessible.role: Accessible.StaticText
Accessible.name: root.pluginCount
+ " Plugins"
}
Item { Layout.fillWidth: true }
CText {
visible: root.lastHealthCheck.length > 0
variant: "caption"
text: "Last check: "
+ root.lastHealthCheck
color: Theme.textSecondary
}
CText {
visible: root.serviceVersion.length > 0
variant: "caption"
text: "v" + root.serviceVersion
color: Theme.textSecondary
}
}
}
}