fix(StatusInput): fixing various layout issues (#794)

- Resolved binding loops in StatusInput
- Replaced all instances of StatusBaseinput
  with StatusInput
- Cleaned up min/max height properties
- Fixed total height calculation

Needed for https://github.com/status-im/status-desktop/issues/6358
This commit is contained in:
Alexandra Betouni 2022-07-25 13:19:26 +03:00 committed by Michał Cieślak
parent 6ed0219313
commit c5a1e057ec
11 changed files with 106 additions and 102 deletions

View File

@ -67,16 +67,16 @@ StatusAppThreePanelLayout {
}
}
StatusBaseInput {
StatusInput {
id: searchInput
anchors.top: searchInputWrapper.bottom
anchors.topMargin: 16
width: parent.width
implicitHeight: 36
maximumHeight: 36
topPadding: 8
bottomPadding: 8
placeholderText: "Search"
icon.name: "search"
input.icon.name: "search"
}
Column {

View File

@ -36,7 +36,7 @@ ColumnLayout {
Layout.fillWidth: true
input.icon.name: "search"
input.placeholderText: "nickname.."
placeholderText: "nickname.."
}
StatusIconTabButton {

View File

@ -37,7 +37,7 @@ Item {
rightPadding: 0
label: qsTr("Select tags that will fit your Community")
input.icon.name: "search"
input.placeholderText: qsTr("Search tags")
placeholderText: qsTr("Search tags")
Layout.fillWidth: true
}
@ -80,4 +80,4 @@ Item {
Layout.fillHeight: true
}
}
}
}

View File

@ -12,22 +12,22 @@ Column {
spacing: 8
StatusInput {
input.placeholderText: "Placeholder"
placeholderText: "Placeholder"
}
StatusInput {
label: "Label"
input.placeholderText: "Disabled"
placeholderText: "Disabled"
input.enabled: false
}
StatusInput {
input.placeholderText: "Clearable"
placeholderText: "Clearable"
input.clearable: true
}
StatusInput {
input.placeholderText: "Invalid"
placeholderText: "Invalid"
input.valid: false
}
@ -35,25 +35,25 @@ Column {
label: "Label"
input.icon.name: "search"
input.placeholderText: "Input with icon"
placeholderText: "Input with icon"
}
StatusInput {
label: "Label"
input.placeholderText: "Placeholder"
placeholderText: "Placeholder"
input.clearable: true
}
StatusInput {
charLimit: 30
input.placeholderText: "Placeholder"
placeholderText: "Placeholder"
input.clearable: true
}
StatusInput {
label: "Label"
charLimit: 30
input.placeholderText: "Placeholder"
placeholderText: "Placeholder"
input.clearable: true
}
@ -91,7 +91,7 @@ Column {
errorMessage: "Error message"
input.clearable: true
input.valid: false
input.placeholderText: "Placeholder"
placeholderText: "Placeholder"
}
StatusInput {
@ -106,7 +106,7 @@ Column {
StatusInput {
label: "Label"
secondaryLabel: "secondary label"
input.placeholderText: "Placeholder"
placeholderText: "Placeholder"
input.implicitHeight: 56
}
@ -114,7 +114,7 @@ Column {
id: input
label: "Label"
charLimit: 30
input.placeholderText: "Input with validator"
placeholderText: "Input with validator"
validators: [
StatusMinLengthValidator {
@ -132,7 +132,7 @@ Column {
StatusInput {
label: "Input with <i>StatusRegularExpressionValidator</i>"
charLimit: 30
input.placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
validationMode: StatusInput.ValidationMode.IgnoreInvalidInput
validators: [
@ -145,7 +145,7 @@ Column {
StatusInput {
label: "Label"
input.placeholderText: "Input width component (right side)"
placeholderText: "Input width component (right side)"
input.rightComponent: StatusIcon {
icon: "cancel"
height: 16
@ -156,26 +156,26 @@ Column {
StatusInput {
input.multiline: true
input.placeholderText: "Multiline"
placeholderText: "Multiline"
}
StatusInput {
input.multiline: true
input.placeholderText: "Multiline with static height"
placeholderText: "Multiline with static height"
input.implicitHeight: 100
}
StatusInput {
input.multiline: true
input.placeholderText: "Multiline with max/min"
input.minimumHeight: 80
input.maximumHeight: 200
placeholderText: "Multiline with max/min"
minimumHeight: 80
maximumHeight: 200
}
StatusInput {
property bool toggled: true
label: "Input with emoji icon"
input.placeholderText: "Enter Name"
placeholderText: "Enter Name"
input.icon.emoji: toggled ? "😁" : "🧸"
input.icon.color: "blue"
input.isIconSelectable: true
@ -187,7 +187,7 @@ Column {
StatusInput {
property bool toggled: true
label: "Input with selectable icon which is not an emoji"
input.placeholderText: "Enter Name"
placeholderText: "Enter Name"
input.icon.emoji: ""
input.icon.name: toggled ? "filled-account" : "image"
input.icon.color: "blue"

View File

@ -12,7 +12,7 @@ import StatusQ.Controls 0.1
\since StatusQ.Components 0.1
\brief This component represents a StatusCard as defined in design under https://www.figma.com/file/FkFClTCYKf83RJWoifWgoX/Wallet-v2?node-id=3161%3A171040
There is an advanced mode avialable where a StatusBaseInput is provided for the user to be able to change values.
There is an advanced mode available where a StatusInput is provided for the user to be able to change values.
Example of how the component looks like:
\image status_card.png
@ -80,7 +80,7 @@ Rectangle {
property alias tertiaryText: tertiaryText.text
/*!
\qmlproperty alias StatusCard::advancedInputText
Used to set text in the StatusBaseInput in advancedMode
Used to set text in the StatusInput in advancedMode
*/
property alias advancedInputText: advancedInput.text
/*!
@ -111,7 +111,7 @@ Rectangle {
property alias tertiaryLabel: tertiaryText
/*!
\qmlproperty alias StatusCard::advancedInput
This property allows user to customize the StatusBaseInput in advanced mode
This property allows user to customize the StatusInput in advanced mode
*/
property alias advancedInput: advancedInput
/*!
@ -191,18 +191,18 @@ Rectangle {
}
}
StatusBaseInput {
StatusInput {
id: advancedInput
property bool locked: false
implicitWidth: 80
implicitHeight: 32
maximumHeight: 32
topPadding: 0
bottomPadding: 0
leftPadding: 8
rightPadding: 5
edit.font.pixelSize: 13
edit.readOnly: locked || disabled
rightComponent: Row {
input.edit.font.pixelSize: 13
input.edit.readOnly: locked || disabled
input.rightComponent: Row {
width: implicitWidth
spacing: 4
StatusFlatRoundButton {

View File

@ -298,9 +298,9 @@ Item {
color: Theme.palette.statusPopupMenu.backgroundColor
z: 3 // Above delegate (z=1) and above section.delegate (z = 2)
StatusBaseInput {
StatusInput {
id: searchInput
implicitHeight: 36
maximumHeight: 36
width: content.itemWidth - 2 * 18
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
@ -308,7 +308,7 @@ Item {
bottomPadding: 0
placeholderText: root.placeholderSearchText
text: root.searchText
icon.name: "search"
input.icon.name: "search"
onTextChanged: {
d.applyFilter(text)

View File

@ -26,7 +26,7 @@ Item {
// To-Do: Move to StatusChatInput once its moved to StatusQ
sourceComponent: StatusInput {
width: editText.width
input.placeholderText: ""
placeholderText: ""
input.text: msgText
input.implicitHeight: 40
}

View File

@ -174,17 +174,6 @@ Item {
This property sets the tab key navigation item.
*/
property var tabNavItem: null
/*!
\qmlproperty real StatusBaseInput::minimumHeight
This property sets the minimum height.
*/
property real minimumHeight: 0
/*!
\qmlproperty alias StatusBaseInput::maximumHeight
This property sets the maximum height.
*/
property real maximumHeight: 0
/*!
\qmlproperty int StatusBaseInput::maximumLength
This property sets the text's maximum length.
@ -277,20 +266,10 @@ Item {
*/
signal editClicked()
implicitWidth: 448
implicitHeight: multiline ? Math.min(Math.max(
(edit.implicitHeight + topPadding + bottomPadding),
44, root.minimumHeight), root.maximumHeight) : 44
Rectangle {
id: background
width: parent.width
height: maximumHeight != 0 ? Math.min(
minimumHeight
!= 0 ? Math.max(
root.implicitHeight,
minimumHeight) : root.implicitHeight,
maximumHeight) : parent.height
anchors.fill: parent
color: root.showBackground ? Theme.palette.baseColor2
: "transparent"
radius: 8
@ -324,10 +303,10 @@ Item {
root.editClicked()
}
RowLayout {
spacing: 10
spacing: 2
anchors {
fill: parent
leftMargin: root.leftPadding ? root.leftPadding : leftComponentLoader.item ? 8 : 16
leftMargin: root.leftPadding ? root.leftPadding : leftComponentLoader.item ? 6 : 16
rightMargin: root.rightPadding
}
@ -346,12 +325,10 @@ Item {
Flickable {
id: flick
Layout.fillHeight: true
Layout.fillWidth: true
Layout.fillHeight: true
Layout.topMargin: root.topPadding
Layout.bottomMargin: root.bottomPadding
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
boundsBehavior: Flickable.StopAtBounds
@ -374,10 +351,8 @@ Item {
TextEdit {
id: edit
property string previousText: text
property var keyEvent
width: flick.width
height: flick.height
verticalAlignment: TextEdit.AlignVCenter
@ -389,7 +364,6 @@ Item {
font.family: Theme.palette.baseFont.name
color: root.enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
wrapMode: root.multiline ? Text.WrapAtWordBoundaryOrAnywhere : TextEdit.NoWrap
Keys.onReturnPressed: event.accepted = !multiline && !acceptReturn
Keys.onEnterPressed: event.accepted = !multiline && !acceptReturn
Keys.forwardTo: [root]
@ -399,7 +373,6 @@ Item {
edit.keyEvent = event.key
root.keyPressed(event);
}
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
onActiveFocusChanged: if (root.pristine) root.pristine = false
onTextChanged: {

View File

@ -22,7 +22,7 @@ import StatusQ.Controls.Validators 0.1
charLimit: 30
errorMessage: qsTr("Input doesn't match validator")
input.clearable: true
input.placeholderText: qsTr("Placeholder text")
placeholderText: qsTr("Placeholder text")
}
\endqml
@ -58,11 +58,21 @@ Item {
This property holds a reference to the TextEdit's text property.
*/
property alias text: statusBaseInput.text
/*!
\qmlproperty alias StatusInput::placeholderText
This property holds a reference to the TextEdit's placeholderText property.
*/
property alias placeholderText: statusBaseInput.placeholderText
/*!
\qmlproperty alias StatusInput::font
This property holds a reference to the TextEdit's font property.
*/
property alias font: statusBaseInput.font
/*!
\qmlproperty alias StatusInput::multiline
This property indicates whether the StatusBaseInput allows multiline text. Default value is false.
*/
property alias multiline: statusBaseInput.multiline
/*!
\qmlproperty errorMessageCmp
@ -101,15 +111,35 @@ Item {
*/
property string errorMessage: ""
/*!
\qmlproperty real StatusBaseInput::leftPadding
\qmlproperty alias StatusInput::leftPadding
This property sets the leftComponentLoader's left padding.
*/
property real leftPadding: 16
property alias leftPadding: statusBaseInput.leftPadding
/*!
\qmlproperty real StatusBaseInput::rightPadding
\qmlproperty alias StatusInput::rightPadding
This property sets the right padding.
*/
property real rightPadding: 16
property alias rightPadding: statusBaseInput.rightPadding
/*!
\qmlproperty alias StatusInput::topPadding
This property sets the top padding.
*/
property alias topPadding: statusBaseInput.topPadding
/*!
\qmlproperty alias StatusInput::bottomPadding
This property sets the bottom padding.
*/
property alias bottomPadding: statusBaseInput.bottomPadding
/*!
\qmlproperty real StatusInput::minimumHeight
This property sets the minimum height.
*/
property real minimumHeight: 0
/*!
\qmlproperty alias StatusInput::maximumHeight
This property sets the maximum height.
*/
property real maximumHeight: 0
/*!
\qmlproperty list StatusBaseInput::validators
This property sets the list of validators to be considered.
@ -310,24 +340,32 @@ Item {
root.valid = Object.values(asyncErrors).length == 0
}
implicitWidth: inputLayout.implicitWidth
implicitHeight: inputLayout.implicitHeight
height: implicitHeight
width: implicitWidth
QtObject {
id: internal
readonly property int inputHeight: statusBaseInput.multiline || (root.minimumHeight > 0) || (root.maximumHeight > 0)?
Math.min(Math.max(statusBaseInput.topPadding + statusBaseInput.bottomPadding, 44,
root.minimumHeight), root.maximumHeight) : 44
}
Component.onCompleted: validate()
implicitWidth: 448
implicitHeight: (internal.inputHeight + topRow.height + errorMessage.height + (2*inputLayout.spacing))
Component.onCompleted: {
validate()
}
ColumnLayout {
id: inputLayout
anchors.fill: parent
spacing: ((topRow.height > 0) || (errorMessage.height > 0)) ? 8 : 0
RowLayout {
id: topRow
Layout.fillWidth: true
Layout.preferredHeight: (!!root.label || !!root.secondaryLabel || root.charLimit > 0) ? 22 :0
StatusBaseText {
id: label
visible: !!root.label
visible: !!text
height: visible ? contentHeight : 0
elide: Text.ElideRight
text: root.label
font.pixelSize: 15
@ -340,6 +378,7 @@ Item {
elide: Text.ElideRight
text: root.secondaryLabel
font.pixelSize: 15
height: visible ? contentHeight : 0
color: Theme.palette.baseColor1
}
@ -349,9 +388,9 @@ Item {
StatusBaseText {
id: charLimitLabel
Layout.alignment: Qt.AlignVCenter
height: visible ? contentHeight : 0
visible: root.charLimit > 0
text: "%1 / %2".arg(statusBaseInput.text.length).arg(root.charLimit)
font.pixelSize: 12
color: statusBaseInput.enabled ? Theme.palette.baseColor1 : Theme.palette.directColor6
@ -360,16 +399,10 @@ Item {
StatusBaseInput {
id: statusBaseInput
Layout.fillWidth: true
Layout.fillHeight: true
leftPadding: root.leftPadding
rightPadding: root.rightPadding
implicitWidth: parent.width
implicitHeight: internal.inputHeight
maximumLength: root.charLimit
onTextChanged: root.validate()
Keys.forwardTo: [root]
onIconClicked: root.iconClicked()
onKeyPressed: {
@ -382,13 +415,11 @@ Item {
StatusBaseText {
id: errorMessage
visible: !!text && !statusBaseInput.valid
height: visible ? contentHeight : 0
font.pixelSize: 12
color: Theme.palette.dangerColor1
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignVCenter
wrapMode: Text.WordWrap
}
}

View File

@ -89,7 +89,7 @@ StatusModal {
color: Theme.palette.baseColor1
}
StatusBaseInput {
StatusInput {
id: inputText
anchors.left: statusIcon.right
anchors.right: parent.right
@ -99,9 +99,9 @@ StatusModal {
leftPadding: 5
topPadding: 5 //smaller padding to handle bigger font
bottomPadding: 5
clearable: true
showBackground: false
placeholder {
input.clearable: true
input.showBackground: false
input.placeholder {
text: qsTr("Search")
font.pixelSize: 28
color: Theme.palette.directColor9

View File

@ -19,7 +19,7 @@ Item {
id: statusInput
label: "Control under test"
charLimit: 30
input.placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
placeholderText: `Must match regex(${validators[0].regularExpression.toString()}) and <= 30 chars`
focus: true
validators: [