diff --git a/storybook/pages/AssetSelectorCompactPage.qml b/storybook/pages/AssetSelectorCompactPage.qml new file mode 100644 index 0000000000..a61555166d --- /dev/null +++ b/storybook/pages/AssetSelectorCompactPage.qml @@ -0,0 +1,95 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import AppLayouts.Wallet.controls 1.0 +import StatusQ.Core.Theme 0.1 +import utils 1.0 + +Pane { + readonly property var assetsData: [ + { + tokensKey: "key_1", + communityId: "", + name: "Status Test Token", + currencyBalanceAsString: "42,23 USD", + symbol: "STT", + iconSource: Constants.tokenIcon("STT"), + tokensKey: "STT", + + balances: [ + { + balanceAsString: "0,56", + iconUrl: "network/Network=Ethereum" + } + ], + + sectionText: "My assets on Mainnet" + }, + { + tokensKey: "key_2", + communityId: "", + name: "Ether", + currencyBalanceAsString: "4 276,86 USD", + symbol: "ETH", + iconSource: Constants.tokenIcon("ETH"), + tokensKey: "ETH", + + balances: [ + { + balanceAsString: "0,12", + iconUrl: "network/Network=Ethereum" + } + ], + + sectionText: "My assets on Mainnet" + }, + { + tokensKey: "key_2", + communityId: "", + name: "Dai Stablecoin", + currencyBalanceAsString: "45,92 USD", + symbol: "DAI", + iconSource: Constants.tokenIcon("DAI"), + tokensKey: "DAI", + balances: [], + + sectionText: "Popular assets" + }, + { + tokensKey: "key_3", + communityId: "", + name: "0x", + currencyBalanceAsString: "41,22 USD", + symbol: "ZRX", + iconSource: Constants.tokenIcon("ZRX"), + tokensKey: "ZRX", + balances: [], + + sectionText: "Popular assets" + } + ] + + ListModel { + id: assetsModel + + Component.onCompleted: append(assetsData) + } + + background: Rectangle { + color: Theme.palette.baseColor3 + } + + AssetSelectorCompact { + id: panel + + anchors.centerIn: parent + width: 400 + + model: assetsModel + sectionProperty: "sectionText" + + onSelected: console.log("asset selected:", key) + } +} + +// category: Controls diff --git a/storybook/pages/AssetSelectorPage.qml b/storybook/pages/AssetSelectorPage.qml index 175e361ae8..f6c896510b 100644 --- a/storybook/pages/AssetSelectorPage.qml +++ b/storybook/pages/AssetSelectorPage.qml @@ -20,16 +20,10 @@ Pane { { balanceAsString: "0,56", iconUrl: "network/Network=Ethereum" - }, - { - balanceAsString: "0,22", - iconUrl: "network/Network=Arbitrum" - }, - { - balanceAsString: "0,12", - iconUrl: "network/Network=Optimism" } - ] + ], + + sectionText: "My assets on Mainnet" }, { tokensKey: "key_2", @@ -41,19 +35,13 @@ Pane { tokensKey: "ETH", balances: [ - { - balanceAsString: "1,01", - iconUrl: "network/Network=Optimism" - }, - { - balanceAsString: "0,47", - iconUrl: "network/Network=Arbitrum" - }, { balanceAsString: "0,12", iconUrl: "network/Network=Ethereum" } - ] + ], + + sectionText: "My assets on Mainnet" }, { tokensKey: "key_2", @@ -63,21 +51,21 @@ Pane { symbol: "DAI", iconSource: Constants.tokenIcon("DAI"), tokensKey: "DAI", + balances: [], - balances: [ - { - balanceAsString: "45,12", - iconUrl: "network/Network=Arbitrum" - }, - { - balanceAsString: "0,56", - iconUrl: "network/Network=Optimism" - }, - { - balanceAsString: "0,12", - iconUrl: "network/Network=Ethereum" - } - ] + sectionText: "Popular assets" + }, + { + tokensKey: "key_3", + communityId: "", + name: "0x", + currencyBalanceAsString: "41,22 USD", + symbol: "ZRX", + iconSource: Constants.tokenIcon("ZRX"), + tokensKey: "ZRX", + balances: [], + + sectionText: "Popular assets" } ] @@ -96,9 +84,10 @@ Pane { anchors.centerIn: parent - assetsModel: assetsModel + model: assetsModel + sectionProperty: "sectionText" - onAssetSelected: console.log("asset selected:", key) + onSelected: console.log("asset selected:", key) } } diff --git a/storybook/pages/SearchableAssetsPanelPage.qml b/storybook/pages/SearchableAssetsPanelPage.qml new file mode 100644 index 0000000000..5ffdd284ba --- /dev/null +++ b/storybook/pages/SearchableAssetsPanelPage.qml @@ -0,0 +1,112 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Controls 2.15 + +import AppLayouts.Wallet.panels 1.0 +import utils 1.0 + +Pane { + readonly property var assetsData: [ + { + tokensKey: "key_1", + communityId: "", + name: "Status Test Token", + currencyBalanceAsString: "42,23 USD", + symbol: "STT", + iconSource: Constants.tokenIcon("STT"), + tokensKey: "STT", + balances: [ + { + balanceAsString: "0,56", + iconUrl: "network/Network=Ethereum" + }, + { + balanceAsString: "0,22", + iconUrl: "network/Network=Arbitrum" + }, + { + balanceAsString: "0,12", + iconUrl: "network/Network=Optimism" + } + ], + + sectionText: "" + }, + { + tokensKey: "key_2", + communityId: "", + name: "Ether", + currencyBalanceAsString: "4 276,86 USD", + symbol: "ETH", + iconSource: Constants.tokenIcon("ETH"), + tokensKey: "ETH", + balances: [ + { + balanceAsString: "1,01", + iconUrl: "network/Network=Optimism" + }, + { + balanceAsString: "0,47", + iconUrl: "network/Network=Arbitrum" + }, + { + balanceAsString: "0,12", + iconUrl: "network/Network=Ethereum" + } + ], + + sectionText: "" + }, + { + tokensKey: "key_2", + communityId: "", + name: "Dai Stablecoin", + currencyBalanceAsString: "45,92 USD", + symbol: "DAI", + iconSource: Constants.tokenIcon("DAI"), + tokensKey: "DAI", + balances: [], + + sectionText: "Popular assets" + }, + { + tokensKey: "key_3", + communityId: "", + name: "0x", + currencyBalanceAsString: "41,22 USD", + symbol: "ZRX", + iconSource: Constants.tokenIcon("ZRX"), + tokensKey: "ZRX", + balances: [], + + sectionText: "Popular assets" + } + ] + + ListModel { + id: assetsModel + + Component.onCompleted: append(assetsData) + } + + Rectangle { + anchors.fill: panel + anchors.margins: -1 + + color: "transparent" + border.color: "lightgray" + } + + SearchableAssetsPanel { + id: panel + + anchors.centerIn: parent + + width: 350 + + model: assetsModel + sectionProperty: "sectionText" + } +} + +// category: Panels diff --git a/storybook/pages/TokenSelectorCompactButtonPage.qml b/storybook/pages/TokenSelectorCompactButtonPage.qml new file mode 100644 index 0000000000..42a6819daf --- /dev/null +++ b/storybook/pages/TokenSelectorCompactButtonPage.qml @@ -0,0 +1,60 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import Qt.labs.settings 1.1 + +import AppLayouts.Wallet.controls 1.0 +import StatusQ.Core.Theme 0.1 +import utils 1.0 + +Pane { + padding: 0 + + Rectangle { + anchors.fill: parent + color: Theme.palette.baseColor3 + } + + RowLayout { + anchors.centerIn: parent + + width: 400 + height: 60 + + TokenSelectorCompactButton { + id: panel + + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter + + selected: selectionCheckBox.checked + + name: "My token" + (longNameCheckBox.checked + ? " long".repeat(10) : "") + subname: "MTKN" + icon: Constants.tokenIcon("CFI") + } + } + + ColumnLayout { + CheckBox { + id: selectionCheckBox + + text: "selected" + } + + CheckBox { + id: longNameCheckBox + + text: "long name" + } + } + + Settings { + property alias selected: selectionCheckBox.checked + property alias longName: longNameCheckBox.checked + } +} + +// category: Controls diff --git a/ui/app/AppLayouts/Wallet/controls/AssetSelector.qml b/ui/app/AppLayouts/Wallet/controls/AssetSelector.qml index 95cbecd041..4013952d62 100644 --- a/ui/app/AppLayouts/Wallet/controls/AssetSelector.qml +++ b/ui/app/AppLayouts/Wallet/controls/AssetSelector.qml @@ -12,31 +12,26 @@ Control { id: root /** Expected model structure: see SearchableAssetsPanel::model **/ - property alias assetsModel: searchableAssetsPanel.model + property alias model: searchableAssetsPanel.model - readonly property bool isTokenSelected: d.isTokenSelected + property alias sectionProperty: searchableAssetsPanel.sectionProperty - signal assetSelected(string key) + readonly property bool isSelected: button.selected + + signal selected(string key) function setCustom(name: string, icon: url, key: string) { - d.isTokenSelected = true - tokenSelectorButton.name = name - tokenSelectorButton.icon = icon + button.name = name + button.icon = icon + button.selected = true + searchableAssetsPanel.highlightedKey = key ?? "" } - QtObject { - id: d - - property bool isTokenSelected: false - } - contentItem: TokenSelectorButton { - id: tokenSelectorButton + id: button - selected: d.isTokenSelected forceHovered: dropdown.opened - text: qsTr("Select asset") onClicked: dropdown.opened ? dropdown.close() : dropdown.open() @@ -47,25 +42,25 @@ Control { y: parent.height + 4 - closePolicy: Popup.CloseOnPressOutsideParent + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent padding: 0 contentItem: SearchableAssetsPanel { id: searchableAssetsPanel function setCurrentAndClose(name, icon) { - tokenSelectorButton.name = name - tokenSelectorButton.icon = icon - d.isTokenSelected = true + button.name = name + button.icon = icon + button.selected = true dropdown.close() } onSelected: { - const entry = ModelUtils.getByKey(assetsModel, "tokensKey", key) + const entry = ModelUtils.getByKey(root.model, "tokensKey", key) highlightedKey = key setCurrentAndClose(entry.symbol, entry.iconSource) - root.assetSelected(key) + root.selected(key) } } } diff --git a/ui/app/AppLayouts/Wallet/controls/AssetSelectorCompact.qml b/ui/app/AppLayouts/Wallet/controls/AssetSelectorCompact.qml new file mode 100644 index 0000000000..bee468e3b7 --- /dev/null +++ b/ui/app/AppLayouts/Wallet/controls/AssetSelectorCompact.qml @@ -0,0 +1,74 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import StatusQ.Controls 0.1 +import StatusQ.Core.Utils 0.1 + +import AppLayouts.Wallet.panels 1.0 + +import utils 1.0 + +Control { + id: root + + /** Expected model structure: see SearchableAssetsPanel::model **/ + property alias model: searchableAssetsPanel.model + + property alias sectionProperty: searchableAssetsPanel.sectionProperty + + readonly property bool isSelected: button.selected + + signal selected(string key) + + function setCustom(name: string, symbol: string, icon: url, key: string) { + button.name = name + button.subname = symbol + button.icon = icon + button.selected = true + + searchableAssetsPanel.highlightedKey = key ?? "" + } + + function reset() { + button.selected = false + } + + contentItem: TokenSelectorCompactButton { + id: button + + objectName: "assetSelectorButton" + + onClicked: dropdown.opened ? dropdown.close() : dropdown.open() + } + + StatusDropdown { + id: dropdown + + y: parent.height + 4 + width: parent.width + + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent + padding: 0 + + contentItem: SearchableAssetsPanel { + id: searchableAssetsPanel + + function setCurrentAndClose(name, symbol, icon) { + button.name = name + button.subname = symbol + button.icon = icon + button.selected = true + + dropdown.close() + } + + onSelected: { + const entry = ModelUtils.getByKey(root.model, "tokensKey", key) + highlightedKey = key + + setCurrentAndClose(entry.name, entry.symbol, entry.iconSource) + root.selected(key) + } + } + } +} diff --git a/ui/app/AppLayouts/Wallet/controls/TokenSelectorCompactButton.qml b/ui/app/AppLayouts/Wallet/controls/TokenSelectorCompactButton.qml new file mode 100644 index 0000000000..c61340d5ca --- /dev/null +++ b/ui/app/AppLayouts/Wallet/controls/TokenSelectorCompactButton.qml @@ -0,0 +1,113 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import StatusQ.Components 0.1 +import StatusQ.Components.private 0.1 +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 + +import utils 1.0 + +Control { + id: root + + property bool selected + + property string text: qsTr("Select asset") + + property string name + property string subname + property url icon + + signal clicked + + padding: 10 + + background: StatusComboboxBackground { + border.width: 1 + color: Theme.palette.transparent + } + + contentItem: Loader { + sourceComponent: root.selected ? selectedContent : notSelectedContent + } + + Component { + id: notSelectedContent + + RowLayout { + spacing: 10 + + StatusBaseText { + Layout.fillWidth: true + + objectName: "tokenSelectorContentItemText" + font.pixelSize: Style.current.additionalTextSize + font.weight: Font.Medium + color: Theme.palette.primaryColor1 + text: root.text + + elide: Text.ElideRight + } + + StatusComboboxIndicator { + color: Theme.palette.primaryColor1 + } + } + } + + Component { + id: selectedContent + + RowLayout { + spacing: Style.current.halfPadding + + RowLayout { + objectName: "selectedTokenItem" + spacing: Style.current.halfPadding + + StatusRoundedImage { + objectName: "tokenSelectorIcon" + Layout.preferredWidth: 20 + Layout.preferredHeight: 20 + image.source: root.icon + } + + StatusBaseText { + objectName: "tokenSelectorContentItemName" + + Layout.fillWidth: true + + // Using Math.ceil prevents undesired elision for some texts + Layout.maximumWidth: Math.ceil(implicitWidth) + + color: Theme.palette.directColor1 + text: root.name + + elide: Text.ElideRight + } + + StatusBaseText { + objectName: "tokenSelectorContentItemSymbol" + + Layout.fillWidth: true + + color: Theme.palette.baseColor1 + text: root.subname + } + + StatusComboboxIndicator { + color: Theme.palette.primaryColor1 + } + } + } + } + + MouseArea { + cursorShape: root.enabled ? Qt.PointingHandCursor : undefined + anchors.fill: parent + + onClicked: root.clicked() + } +} diff --git a/ui/app/AppLayouts/Wallet/controls/qmldir b/ui/app/AppLayouts/Wallet/controls/qmldir index 54d8677825..531f52e1d6 100644 --- a/ui/app/AppLayouts/Wallet/controls/qmldir +++ b/ui/app/AppLayouts/Wallet/controls/qmldir @@ -1,6 +1,7 @@ AccountHeaderGradient 1.0 AccountHeaderGradient.qml ActivityFilterTagItem 1.0 ActivityFilterTagItem.qml AssetSelector 1.0 AssetSelector.qml +AssetSelectorCompact 1.0 AssetSelectorCompact.qml BuyCryptoProvidersDelegate 1.0 BuyCryptoProvidersDelegate.qml BuyCryptoProvidersLoadingDelegate 1.0 BuyCryptoProvidersLoadingDelegate.qml CollectibleBalanceTag 1.0 CollectibleBalanceTag.qml @@ -24,4 +25,5 @@ SwapExchangeButton 1.0 SwapExchangeButton.qml SwapProvidersTermsAndConditionsText 1.0 SwapProvidersTermsAndConditionsText.qml TokenSelector 1.0 TokenSelector.qml TokenSelectorButton 1.0 TokenSelectorButton.qml +TokenSelectorCompactButton 1.0 TokenSelectorCompactButton.qml TokenSelectorNew 1.0 TokenSelectorNew.qml