Skip to content

Commit

Permalink
feat: [UI - Swap] Create tag error component
Browse files Browse the repository at this point in the history
- created a new component (`ErrorTag`) based on the existing
`InformationTag`, suitable for displaying a row of icon (optional), text
and (optional) button in red/danger color
- add ErrorTagPage.qml to StoryBook
- add some basic QML tests

- InformationTag: make more properties customizable, use the same
`bgRadius` consistently
- StatusSmartIdenticon: some fixes for the MouseArea hover/click
behavior

Fixes #14792
  • Loading branch information
caybro committed May 23, 2024
1 parent df3f998 commit a2e85bb
Show file tree
Hide file tree
Showing 7 changed files with 252 additions and 27 deletions.
95 changes: 95 additions & 0 deletions storybook/pages/ErrorTagPage.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15

import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1

import shared.controls 1.0

import Storybook 1.0

SplitView {
orientation: Qt.Horizontal

Logs { id: logs }

Pane {
SplitView.fillWidth: true
SplitView.fillHeight: true

background: Rectangle {
color: Theme.palette.baseColor4
}

ErrorTag {
width: ctrlWidth.value || implicitWidth
anchors.centerIn: parent
text: ctrlText.text
buttonText: ctrlButtonText.text
asset.name: ctrlAssetName.text
loading: ctrlLoading.checked
onButtonClicked: logs.logEvent("ErrorTag::onButtonClicked", [], arguments)
}
}

LogsAndControlsPanel {
SplitView.fillHeight: true
SplitView.preferredWidth: 300

logsView.logText: logs.logText

ColumnLayout {
anchors.fill: parent

RowLayout {
Layout.fillWidth: true
Label { text: "Text:" }
TextField {
Layout.fillWidth: true
id: ctrlText
text: "Insufficient funds to pay gas fees"
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Button text:" }
TextField {
Layout.fillWidth: true
id: ctrlButtonText
text: "Buy ETH"
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Asset name:" }
TextField {
Layout.fillWidth: true
id: ctrlAssetName
text: "warning"
}
}
RowLayout {
Layout.fillWidth: true
Label { text: "Width:" }
SpinBox {
id: ctrlWidth
from: 0
to: 400
value: 0 // 0 == implicitWidth
stepSize: 20
textFromValue: function(value, locale) { return value === 0 ? "Implicit" : value }
}
}
Switch {
id: ctrlLoading
text: "Loading"
}
Item { Layout.fillHeight: true }
}
}
}

// category: Controls

// https://www.figma.com/design/TS0eQX9dAZXqZtELiwKIoK/Swap---Milestone-1?node-id=3413-311788&t=D3qGKqNjDBuLEEaD-0
68 changes: 68 additions & 0 deletions storybook/qmlTests/tests/tst_ErrorTag.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import QtQuick 2.15
import QtTest 1.15

import shared.controls 1.0

Item {
id: root
width: 600
height: 400

Component {
id: componentUnderTest
ErrorTag {
anchors.centerIn: parent
text: "Insufficient funds to pay gas fees"
}
}

SignalSpy {
id: signalSpy
target: controlUnderTest
signalName: "buttonClicked"
}

property ErrorTag controlUnderTest: null

TestCase {
name: "ErrorTag"
when: windowShown

function init() {
controlUnderTest = createTemporaryObject(componentUnderTest, root)
signalSpy.clear()
}

function test_basicGeometry() {
verify(!!controlUnderTest)
verify(controlUnderTest.width > 0)
verify(controlUnderTest.height > 0)
}

function test_noDefaultButton() {
verify(!!controlUnderTest)
const button = findChild(controlUnderTest, "rightComponentButton")
tryCompare(button, "visible", false)
}

function test_buttonClick() {
verify(!!controlUnderTest)
controlUnderTest.buttonText = "Buy crypto"
const button = findChild(controlUnderTest, "rightComponentButton")
verify(!!button)
tryCompare(button, "visible", true)
mouseClick(button)
tryCompare(signalSpy, "count", 1)
}

function test_loadingNotClickable() {
verify(!!controlUnderTest)
controlUnderTest.loading = true
const button = findChild(controlUnderTest, "rightComponentButton")
verify(!!button)
tryCompare(button, "visible", false)
mouseClick(button)
tryCompare(signalSpy, "count", 0)
}
}
}
11 changes: 6 additions & 5 deletions ui/StatusQ/src/StatusQ/Components/LoadingComponent.qml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import QtQuick 2.13
import QtQuick.Controls 2.12
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtGraphicalEffects 1.15

import StatusQ.Core.Theme 0.1
import QtGraphicalEffects 1.12

/*!
\qmltype LoadingComponent
\inherits Control
\inqmlmodule StatusQ.Components
\since StatusQ.Components 0.1
\brief A componet that can be used to adding a loading state to a widget
\brief A component that can be used to adding a loading state to a widget
Example:
\qml
Expand Down Expand Up @@ -48,6 +48,7 @@ Control {
color: Theme.palette.statusLoadingHighlight
radius: root.radius
visible: false

LinearGradient {
id: gradient
width: 100
Expand All @@ -62,7 +63,7 @@ Control {
GradientStop { position: 0.8; color: "transparent"}
}
rotation: 20
NumberAnimation on x {
XAnimator on x {
id: animation
easing.type: Easing.Linear
loops: Animation.Infinite
Expand Down
20 changes: 4 additions & 16 deletions ui/StatusQ/src/StatusQ/Components/StatusSmartIdenticon.qml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Loader {
property bool hoverEnabled: false
readonly property bool hovered: (sourceComponent === roundedIcon && item) ?
item.hovered : false

signal clicked(var mouse)

Component {
Expand Down Expand Up @@ -91,18 +92,15 @@ Loader {
asset.bgBorderWidth: root.asset.bgBorderWidth
asset.bgBorderColor: root.asset.bgBorderColor

signal clicked(var mouse)

property alias hovered: mouseArea.containsMouse
readonly property alias hovered: mouseArea.containsMouse

MouseArea {
id: mouseArea

anchors.fill: parent
hoverEnabled: root.hoverEnabled
cursorShape: loading ? Qt.ArrowCursor
: Qt.PointingHandCursor
onClicked: parent.clicked(mouse)
cursorShape: !loading && root.hoverEnabled ? Qt.PointingHandCursor : undefined
onClicked: root.clicked(mouse)
}
}
}
Expand Down Expand Up @@ -168,14 +166,4 @@ Loader {
width: root.asset.isImage ? root.asset.width : root.asset.bgWidth
}
}

Connections {
target: item
enabled: status === Loader.Ready
ignoreUnknownSignals: true

function onClicked(mouse) {
root.clicked(mouse)
}
}
}
69 changes: 69 additions & 0 deletions ui/imports/shared/controls/ErrorTag.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15

import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Controls 0.1

import shared.controls 1.0

InformationTag {
id: root

property string text
property string buttonText

signal buttonClicked()

implicitHeight: 33
leftPadding: 10
rightPadding: 4
verticalPadding: 4
spacing: 6

backgroundColor: Theme.palette.dangerColor3
bgBorderColor: Theme.palette.dangerColor2

QtObject {
id: priv

readonly property int fontPixelSize: Theme.tertiaryTextFontSize
readonly property color foregroundColor: Theme.palette.dangerColor1
}

asset {
name: "warning"
color: priv.foregroundColor
}

tagPrimaryLabel.text: root.text
tagPrimaryLabel.color: priv.foregroundColor
tagPrimaryLabel.font.pixelSize: priv.fontPixelSize
tagPrimaryLabel.elide: Text.ElideRight

// NB: regular binding won't work as `tagPrimaryLabel` is an alias
Binding {
target: tagPrimaryLabel
property: "Layout.fillWidth"
value: true
}

rightComponent: StatusButton {
objectName: "rightComponentButton"
horizontalPadding: 8

width: visible || root.loading ? implicitWidth : 0
visible: !!text

size: StatusBaseButton.Size.Tiny
font.pixelSize: priv.fontPixelSize
type: StatusBaseButton.Type.Danger
normalColor: priv.foregroundColor
hoverColor: Theme.palette.hoverColor(normalColor)
textColor: Theme.palette.white
radius: root.bgRadius
text: root.buttonText
onClicked: root.buttonClicked()
}
}
15 changes: 9 additions & 6 deletions ui/imports/shared/controls/InformationTag.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import QtQuick 2.13
import QtQuick.Layouts 1.13
import QtQuick.Controls 2.14
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15

import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
Expand All @@ -18,20 +18,23 @@ Control {
property alias rightComponent: rightComponent.sourceComponent
property bool loading: false
property int secondarylabelMaxWidth: 100

property color backgroundColor: "transparent"
property color bgBorderColor: Theme.palette.baseColor2
property real bgRadius: 36

property Component customBackground: Component {
Rectangle {
color: root.backgroundColor
border.width: 1
border.color: Theme.palette.baseColor2
radius: 36
border.color: root.bgBorderColor
radius: root.bgRadius
}
}

QtObject {
id: d
property var loadingComponent: Component { LoadingComponent {} }
property var loadingComponent: Component { LoadingComponent { radius: root.bgRadius } }
}

horizontalPadding: 12
Expand Down
1 change: 1 addition & 0 deletions ui/imports/shared/controls/qmldir
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CurrencyAmountInput 1.0 CurrencyAmountInput.qml
EmojiHash 1.0 EmojiHash.qml
EmptyShapeRectangleFooterListView 1.0 EmptyShapeRectangleFooterListView.qml
ErrorDetails 1.0 ErrorDetails.qml
ErrorTag 1.0 ErrorTag.qml
FoldableHeader 1.0 FoldableHeader.qml
FormGroup 1.0 FormGroup.qml
GetSyncCodeDesktopInstructions 1.0 GetSyncCodeDesktopInstructions.qml
Expand Down

0 comments on commit a2e85bb

Please sign in to comment.