Files
metabuilder/qml/components/core/CIconButton.qml
johndoe6345789 eecaac8634 feat(qml): MD3 rework batch 1 — 20 components rewritten
Core: CButton (pill variants), CFab (radius 16 tonal), CIconButton (circle state layers)
Cards: CCard (filled/outlined/elevated, radius 12), CAccordionItem (smooth expand), CPaper
Chips: CChip (8px radius, filter/assist/input), CBadge (6px dot/16px pill), CStatBadge, CStatusBadge
Forms: CTextField (floating label, outlined), CSelect (styled popup), CTextarea (scrollable)
Toggles: CCheckbox (Canvas checkmark), CSwitch (52x32 pill track), CRadio (scale dot), CRating (hover stars)
Feedback: CProgress (4px track, indeterminate slide), CSpinner (Canvas arc sweep), CErrorState (tonal container)

All components: theme-aware, dark/light mode, hover/press state layers, preserved public API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 04:03:18 +00:00

90 lines
2.5 KiB
QML

import QtQuick
import QtQuick.Controls
import QmlComponents 1.0
/**
* CIconButton.qml - Material Design 3 Icon Button
*
* MD3 icon button: 40px circle, transparent background, hover/press state layers.
* Variants:
* default - transparent bg, icon in textSecondary, hover state layer
* primary - transparent bg, icon in primary, hover state layer in primary tint
* ghost - same as default (backward compat)
*/
Item {
id: control
property string icon: ""
property string size: "md" // sm, md, lg
property string variant: "default" // default, primary, ghost
property bool loading: false
property string tooltip: ""
signal clicked()
width: size === "sm" ? 32 : size === "lg" ? 48 : 40
height: width
opacity: enabled ? 1.0 : 0.38
Behavior on opacity { NumberAnimation { duration: Theme.transitionShortest } }
Rectangle {
id: bg
anchors.fill: parent
radius: width / 2
color: "transparent"
Behavior on color { ColorAnimation { duration: Theme.transitionShortest } }
// State layer overlay
Rectangle {
id: stateLayer
anchors.fill: parent
radius: parent.radius
color: control.variant === "primary" ? Theme.primary : (Theme.mode === "dark" ? "#ffffff" : "#000000")
opacity: {
if (!control.enabled) return 0
if (mouseArea.pressed) return 0.12
if (mouseArea.containsMouse) return 0.08
return 0
}
visible: opacity > 0
Behavior on opacity { NumberAnimation { duration: Theme.transitionShortest } }
}
}
BusyIndicator {
anchors.centerIn: parent
width: parent.width * 0.5
height: width
running: control.loading
visible: control.loading
}
Text {
anchors.centerIn: parent
text: control.icon
font.pixelSize: control.size === "sm" ? 16 : control.size === "lg" ? 24 : 20
font.weight: Font.DemiBold
color: {
if (!control.enabled) return Theme.textDisabled
if (control.variant === "primary") return Theme.primary
return Theme.textSecondary
}
visible: !control.loading
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: control.clicked()
}
ToolTip.visible: tooltip && mouseArea.containsMouse
ToolTip.text: tooltip
ToolTip.delay: 500
}