Files
qbz/crates/qbz-qt/qml/controls/IconTextButton.qml
T
vicrodh ed7fa588ea fix(qt): elevated controls lift on hover instead of darkening
Buttons that rest on surfaceElevated used surfaceHover for their hover
fill: a 6% white wash meant for rows that rest transparent. Over an
elevated button it lands DARKER than the rest fill — on a modal's dark
ground the Cancel/Save/footer buttons went near-black under the pointer.

QbzTheme gains surfaceElevatedHover (a lift of surfaceElevated, derived
so every palette has it), its ambient half-alpha twin, and the
elevatedFill / elevatedHoverFill pair an ambient-aware control paints.
Every site with the old pairing (65 across modals, toolbars, selects,
circle actions, chips and cards) now hovers to the lift.

cc
2026-09-14 00:49:54 -06:00

73 lines
2.4 KiB
QML

// Small bordered icon+label button — the QML port of the private
// `IconTextButton` in crates/qbz-ui/ui/shell/LogViewerModal.slint:29-75.
//
// It exists because it AUTO-SIZES TO ITS LABEL. `controls/SettingsButton.qml`
// carries `minWidth: 160`, which is right for a settings row's right rail and
// wrong for a footer of five buttons — using it there overflowed the panel and
// the labels collided (observed 2026-08-05).
//
// Geometry is 1:1 with the reference: height 32, Radius.sm, 1px border-subtle,
// surface-elevated (surface-hover on hover), opacity 0.4 when disabled,
// 12px side padding, 7px gap, 14px icon, 13px medium label. `danger` recolors
// BOTH the icon and the label — it does not fill.
import QtQuick
import com.blitzfc.qbz
import "../theme"
Rectangle {
id: root
property string label: ""
property string iconName: ""
/// The reference's `has-icon`: an icon-less variant keeps the same
/// padding and height.
property bool hasIcon: true
property bool danger: false
property bool btnEnabled: true
signal clicked()
QbzTheme { id: theme }
height: 32
// Auto-size: padding + optional icon + gap + label.
width: 12 + (root.hasIcon ? 14 + 7 : 0) + labelText.implicitWidth + 12
radius: theme.radiusSm
border.width: 1
border.color: theme.borderSubtle
color: hoverArea.containsMouse && root.btnEnabled ? theme.elevatedHoverFill : theme.elevatedFill
opacity: root.btnEnabled ? 1.0 : 0.4
Row {
anchors.centerIn: parent
spacing: 7
QbzIcon {
visible: root.hasIcon
anchors.verticalCenter: parent.verticalCenter
name: root.iconName
width: 14
height: 14
// `favorite` is the port's documented stand-in for the danger red
// (icon_tint_qt.rs:63); there is no `danger` bake.
tintName: root.danger ? "favorite" : "secondary"
}
Text {
id: labelText
anchors.verticalCenter: parent.verticalCenter
text: root.label
color: root.danger ? theme.danger : theme.textSecondary
font.pixelSize: 13
font.weight: theme.weightMedium
}
}
MouseArea {
id: hoverArea
anchors.fill: parent
hoverEnabled: true
cursorShape: root.btnEnabled ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: if (root.btnEnabled) root.clicked()
}
}