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:
parent
795370086b
commit
2f650dc745
|
@ -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 {
|
||||
|
|
|
@ -36,7 +36,7 @@ ColumnLayout {
|
|||
|
||||
Layout.fillWidth: true
|
||||
input.icon.name: "search"
|
||||
input.placeholderText: "nickname.."
|
||||
placeholderText: "nickname.."
|
||||
}
|
||||
|
||||
StatusIconTabButton {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: [
|
||||
|
|
Loading…
Reference in New Issue