mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-24 13:54:57 +00:00
feat(a11y): add Accessible roles, names, objectNames to all core QML components
Core: CButton, CIconButton, CFab, CChip, CListItem — Button roles, activeFocusOnTab Forms: CTextField, CSelect, CCheckbox, CSwitch, CRadio, CRating — EditableText, CheckBox, ComboBox, Slider Feedback: CAlert, CDialog, CSnackbar — AlertMessage, Dialog roles Navigation: CTabBar — PageTabList + PageTab on delegates Data: CAvatar, CBadge, CTable, CStatBadge, CStatusBadge — Graphic, StaticText, Table, Row Surfaces: CCard (Pane), CAccordionItem (Button + expanded), CAppBar (ToolBar) Progress: CProgress (ProgressBar + value), CSpinner (Animation) Divider: CDivider (Separator) 28 files, 157 lines of a11y properties added. Zero to full coverage on core library. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,13 @@ import QmlComponents 1.0
|
||||
Button {
|
||||
id: control
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: text || "Button"
|
||||
Accessible.description: ""
|
||||
activeFocusOnTab: true
|
||||
objectName: "btn_" + text.toLowerCase()
|
||||
.replace(/ /g, "_")
|
||||
|
||||
// default, primary, secondary,
|
||||
// ghost, outlined, danger, text
|
||||
property string variant: "default"
|
||||
|
||||
@@ -39,6 +39,9 @@ Rectangle {
|
||||
? Qt.rgba(1, 1, 1, 0.08)
|
||||
: Qt.rgba(0.31, 0.31, 0.44, 0.10)
|
||||
|
||||
Accessible.role: Accessible.Pane
|
||||
Accessible.name: title
|
||||
|
||||
// Geometry
|
||||
radius: 12
|
||||
clip: true
|
||||
|
||||
@@ -18,6 +18,11 @@ import QmlComponents 1.0
|
||||
Rectangle {
|
||||
id: chip
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: text
|
||||
objectName: "chip_" + text.toLowerCase()
|
||||
.replace(/ /g, "_")
|
||||
|
||||
property string text: ""
|
||||
property string icon: ""
|
||||
// assist, filter, input, suggestion,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QmlComponents 1.0
|
||||
|
||||
/**
|
||||
@@ -10,6 +11,13 @@ import QmlComponents 1.0
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: icon || "Button"
|
||||
Accessible.description: ""
|
||||
activeFocusOnTab: true
|
||||
objectName: "btn_" + (icon || "fab")
|
||||
.toLowerCase().replace(/ /g, "_")
|
||||
|
||||
property alias icon: iconLabel.text
|
||||
property int size: 56
|
||||
|
||||
|
||||
@@ -16,6 +16,13 @@ import QmlComponents 1.0
|
||||
Item {
|
||||
id: control
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: tooltip || icon || "Button"
|
||||
Accessible.description: ""
|
||||
activeFocusOnTab: true
|
||||
objectName: "btn_" + (tooltip || icon)
|
||||
.toLowerCase().replace(/ /g, "_")
|
||||
|
||||
property string icon: ""
|
||||
property string size: "md" // sm, md, lg
|
||||
property string variant: "default" // default, primary, ghost
|
||||
|
||||
@@ -6,6 +6,12 @@ import "../theming"
|
||||
Rectangle {
|
||||
id: listItem
|
||||
|
||||
Accessible.role: Accessible.ListItem
|
||||
Accessible.name: title
|
||||
activeFocusOnTab: true
|
||||
objectName: "listitem_" + title.toLowerCase()
|
||||
.replace(/ /g, "_")
|
||||
|
||||
property string title: ""
|
||||
property string subtitle: ""
|
||||
property string caption: ""
|
||||
|
||||
@@ -40,6 +40,9 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Accessible.role: Accessible.Graphic
|
||||
Accessible.name: initials || "Avatar"
|
||||
|
||||
width: _size
|
||||
height: _size
|
||||
radius: _size / 2
|
||||
|
||||
@@ -45,6 +45,9 @@ Rectangle {
|
||||
|
||||
readonly property bool _showText: !dot && (text !== "" || count > 0)
|
||||
|
||||
Accessible.role: Accessible.StaticText
|
||||
Accessible.name: text || count.toString()
|
||||
|
||||
// MD3 small badge: 6px dot, standard badge: 16px pill
|
||||
width: dot ? 6 : Math.max(16, label.implicitWidth + 8)
|
||||
height: dot ? 6 : 16
|
||||
|
||||
@@ -24,9 +24,12 @@ Item {
|
||||
// MD3: 1px line using outlineVariant (softer than border)
|
||||
readonly property color _lineColor: Theme.border
|
||||
|
||||
Accessible.role: Accessible.Separator
|
||||
|
||||
// Size
|
||||
implicitWidth: orientation === "horizontal" ? 200 : 1
|
||||
implicitHeight: orientation === "horizontal" ? (text ? 24 : 1) : 200
|
||||
implicitHeight: orientation === "horizontal"
|
||||
? (text ? 24 : 1) : 200
|
||||
|
||||
// Horizontal divider
|
||||
Row {
|
||||
|
||||
@@ -63,6 +63,9 @@ Rectangle {
|
||||
|
||||
readonly property var _config: _sizes[size] || _sizes.md
|
||||
|
||||
Accessible.role: Accessible.StaticText
|
||||
Accessible.name: label + ": " + value
|
||||
|
||||
color: _bgColor
|
||||
radius: 12 // MD3 medium container radius
|
||||
|
||||
|
||||
@@ -51,6 +51,9 @@ Rectangle {
|
||||
// MD3 on-container text: full status color
|
||||
readonly property color _textColor: _statusColor
|
||||
|
||||
Accessible.role: Accessible.StaticText
|
||||
Accessible.name: text + " (" + status + ")"
|
||||
|
||||
implicitHeight: 24
|
||||
implicitWidth: badgeRow.implicitWidth + 20
|
||||
radius: 12 // Full pill for status badges
|
||||
|
||||
@@ -29,6 +29,8 @@ Rectangle {
|
||||
property bool sortAscending: true
|
||||
signal headerClicked(int columnIndex)
|
||||
|
||||
Accessible.role: Accessible.Table
|
||||
|
||||
color: "transparent"
|
||||
radius: StyleVariables.radiusSm
|
||||
border.width: bordered ? 1 : 0
|
||||
@@ -131,6 +133,8 @@ Rectangle {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 48
|
||||
|
||||
Accessible.role: Accessible.Row
|
||||
|
||||
property bool hovered: rowMouse.containsMouse
|
||||
|
||||
// MD3: alternating tint + hover state layer (4%)
|
||||
|
||||
@@ -16,6 +16,11 @@ import QmlComponents 1.0
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.AlertMessage
|
||||
Accessible.name: title || text
|
||||
objectName: "alert_" + severity
|
||||
|
||||
// Public properties
|
||||
property string text: ""
|
||||
property string title: ""
|
||||
|
||||
@@ -10,6 +10,12 @@ import QmlComponents 1.0
|
||||
Popup {
|
||||
id: root
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.Dialog
|
||||
Accessible.name: title
|
||||
objectName: "dialog_" + title.toLowerCase()
|
||||
.replace(/ /g, "_")
|
||||
|
||||
property string title: ""
|
||||
property string size: "md" // sm, md, lg, xl
|
||||
property bool showClose: true
|
||||
|
||||
@@ -15,6 +15,11 @@ import QmlComponents 1.0
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.ProgressBar
|
||||
Accessible.name: label || "Progress"
|
||||
Accessible.value: value * 100
|
||||
|
||||
// Public properties
|
||||
property real value: 0 // 0.0 to 1.0
|
||||
property bool indeterminate: false
|
||||
|
||||
@@ -19,6 +19,10 @@ import QmlComponents 1.0
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.AlertMessage
|
||||
Accessible.name: _message
|
||||
|
||||
// Public properties
|
||||
property int duration: 4000 // Auto-hide duration in ms (0 = no auto-hide)
|
||||
property string position: "bottom" // bottom, top
|
||||
|
||||
@@ -16,6 +16,10 @@ import QmlComponents 1.0
|
||||
Item {
|
||||
id: root
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.Animation
|
||||
Accessible.name: "Loading"
|
||||
|
||||
// Public properties
|
||||
property string size: "md" // sm (24px), md (40px), lg (56px)
|
||||
property color color: Theme.primary
|
||||
|
||||
@@ -26,6 +26,14 @@ Item {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
placeholderText: root.placeholderText
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name:
|
||||
root.placeholderText || ""
|
||||
Accessible.description: ""
|
||||
activeFocusOnTab: true
|
||||
objectName: "input_autocomplete"
|
||||
color: Theme.text
|
||||
font.pixelSize: 14
|
||||
font.family: Theme.fontFamily
|
||||
|
||||
@@ -16,6 +16,14 @@ Rectangle {
|
||||
property alias text: label.text
|
||||
property bool enabled: true
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.CheckBox
|
||||
Accessible.name: text
|
||||
Accessible.checked: checked
|
||||
activeFocusOnTab: true
|
||||
objectName: "checkbox_"
|
||||
+ text.toLowerCase().replace(/ /g, "_")
|
||||
|
||||
signal toggled(bool checked)
|
||||
|
||||
width: row.implicitWidth
|
||||
|
||||
@@ -14,6 +14,12 @@ Rectangle {
|
||||
property alias text: label.text
|
||||
property bool enabled: true
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.RadioButton
|
||||
Accessible.name: text
|
||||
Accessible.checked: checked
|
||||
activeFocusOnTab: true
|
||||
|
||||
signal toggled(bool checked)
|
||||
|
||||
width: row.implicitWidth
|
||||
|
||||
@@ -18,6 +18,11 @@ Row {
|
||||
property color filledColor: "#ffc107"
|
||||
property color emptyColor: Theme.border
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.Slider
|
||||
Accessible.name: "Rating"
|
||||
Accessible.value: value
|
||||
|
||||
signal valueChanged(int newValue)
|
||||
|
||||
spacing: 4
|
||||
|
||||
@@ -17,6 +17,11 @@ ComboBox {
|
||||
property bool hasError: errorText.length > 0
|
||||
property string size: "md" // "sm", "md", "lg"
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.ComboBox
|
||||
Accessible.name: label || ""
|
||||
activeFocusOnTab: true
|
||||
|
||||
model: []
|
||||
Layout.preferredWidth: 200
|
||||
implicitHeight: size === "sm"
|
||||
|
||||
@@ -16,6 +16,14 @@ Rectangle {
|
||||
property alias text: label.text
|
||||
property bool enabled: true
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.CheckBox
|
||||
Accessible.name: text
|
||||
Accessible.checked: checked
|
||||
activeFocusOnTab: true
|
||||
objectName: "switch_"
|
||||
+ text.toLowerCase().replace(/ /g, "_")
|
||||
|
||||
signal toggled(bool checked)
|
||||
|
||||
width: row.implicitWidth
|
||||
|
||||
@@ -20,6 +20,15 @@ TextField {
|
||||
property bool clearable: false
|
||||
property string size: "md" // "sm", "md", "lg"
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name: label || placeholderText || ""
|
||||
Accessible.description: helper || ""
|
||||
activeFocusOnTab: true
|
||||
objectName: "input_"
|
||||
+ (label || "field")
|
||||
.toLowerCase().replace(/ /g, "_")
|
||||
|
||||
signal suffixClicked()
|
||||
|
||||
implicitHeight: size === "sm"
|
||||
|
||||
@@ -45,6 +45,17 @@ ScrollView {
|
||||
|
||||
TextArea {
|
||||
id: textArea
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.EditableText
|
||||
Accessible.name:
|
||||
root.label || placeholderText || ""
|
||||
Accessible.description: root.helper || ""
|
||||
activeFocusOnTab: true
|
||||
objectName: "input_"
|
||||
+ (root.label || "field")
|
||||
.toLowerCase().replace(/ /g, "_")
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 14
|
||||
font.family: Theme.fontFamily
|
||||
|
||||
@@ -6,6 +6,10 @@ import "../theming"
|
||||
Rectangle {
|
||||
id: tabBar
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.PageTabList
|
||||
Accessible.name: "Tab bar"
|
||||
|
||||
property int currentIndex: 0
|
||||
property var tabs: [] // [{label, icon}]
|
||||
|
||||
@@ -25,6 +29,12 @@ Rectangle {
|
||||
Rectangle {
|
||||
id: tabDelegate
|
||||
|
||||
// Accessibility
|
||||
Accessible.role: Accessible.PageTab
|
||||
Accessible.name:
|
||||
modelData.label || modelData
|
||||
activeFocusOnTab: true
|
||||
|
||||
readonly property bool isActive:
|
||||
tabBar.currentIndex === index
|
||||
|
||||
|
||||
@@ -31,6 +31,11 @@ Rectangle {
|
||||
readonly property color surfaceContainer:
|
||||
isDark ? Qt.rgba(1, 1, 1, 0.05) : Qt.rgba(0.31, 0.31, 0.44, 0.06)
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: title
|
||||
Accessible.expanded: expanded
|
||||
activeFocusOnTab: true
|
||||
|
||||
// -- Layout --
|
||||
Layout.fillWidth: true
|
||||
radius: 12
|
||||
|
||||
@@ -5,6 +5,8 @@ import QmlComponents 1.0
|
||||
|
||||
ToolBar {
|
||||
id: appbar
|
||||
Accessible.role: Accessible.ToolBar
|
||||
Accessible.name: "Application toolbar"
|
||||
|
||||
background: Rectangle {
|
||||
color: Theme.paper
|
||||
|
||||
Reference in New Issue
Block a user