feat(Storybook): Light/dark mode switch

Moreover:
- load asynchronously switch fixed
- storybook refactored to rely on build-in components only
- some explicit sizes/spacings removed
- some bigger components split into smaller

Closes: #7898
This commit is contained in:
Michał Cieślak 2022-10-14 10:29:36 +02:00 committed by Iuri Matias
parent 057d0c565e
commit 5537f5edd7
7 changed files with 211 additions and 191 deletions

View File

@ -0,0 +1,20 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
ListView {
id: root
spacing: 5
clip: true
property string currentPage
signal pageSelected(string page)
delegate: Button {
width: parent.width
text: model.title
checked: root.currentPage === model.title
onClicked: root.pageSelected(model.title)
}
}

View File

@ -2,4 +2,5 @@ ImageSelectPopup 1.0 ImageSelectPopup.qml
Logs 1.0 Logs.qml
LogsAndControlsPanel 1.0 LogsAndControlsPanel.qml
LogsView 1.0 LogsView.qml
PagesList 1.0 PagesList.qml
singleton StorybookUtils 1.0 StorybookUtils.qml

View File

@ -1,63 +1,82 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import StatusQ.Core 0.1
import StatusQ.Components 0.1
import StatusQ.Layout 0.1
import QtQuick.Layouts 1.14
import Qt.labs.settings 1.0
import StatusQ.Core.Theme 0.1
import Storybook 1.0
ApplicationWindow {
id: rootWindow
id: root
width: 1450
height: 840
visible: true
StatusSectionLayout {
id: mainPageView
property string currentPage
anchors.fill: parent
showHeader: false
font.pixelSize: 13
function page(name, fillPage) {
viewLoader.source = Qt.resolvedUrl("./pages/" + name + "Page.qml");
storeSettings.selected = viewLoader.source
ListModel {
id: pagesModel
ListElement {
title: "CommunitiesPortalLayout"
}
ListElement {
title: "LoginView"
}
}
leftPanel: StatusScrollView {
anchors.fill: parent
anchors.topMargin: 48
SplitView {
anchors.fill: parent
Column {
spacing: 0
ColumnLayout {
SplitView.preferredWidth: 240
CheckBox {
text: "Load asynchronously"
checked: storeSettings.loadAsynchronously
CheckBox {
id: loadAsyncCheckBox
onToggled: storeSettings.loadAsynchronously = checked
Layout.fillWidth: true
text: "Load asynchronously"
}
CheckBox {
id: darkModeCheckBox
Layout.fillWidth: true
text: "Dark mode"
StatusLightTheme { id: lightTheme }
StatusDarkTheme { id: darkTheme }
Binding {
target: Theme
property: "palette"
value: darkModeCheckBox.checked ? darkTheme : lightTheme
}
}
Item { width: 1; height: 30 }
Pane {
Layout.fillWidth: true
Layout.fillHeight: true
StatusNavigationListItem {
title: "CommunitiesPortalLayout"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
}
PagesList {
anchors.fill: parent
StatusNavigationListItem {
title: "LoginView"
selected: viewLoader.source.toString().includes(title)
onClicked: mainPageView.page(title);
currentPage: root.currentPage
model: pagesModel
onPageSelected: root.currentPage = page
}
}
}
centerPanel: Item {
anchors.fill: parent
Item {
SplitView.fillWidth: true
Loader {
id: viewLoader
@ -65,15 +84,14 @@ ApplicationWindow {
anchors.fill: parent
clip: true
source: storeSettings.selected
asynchronous: storeSettings.loadAsynchronously
source: Qt.resolvedUrl(`./pages/${root.currentPage}Page.qml`)
asynchronous: loadAsyncCheckBox.checked
visible: status === Loader.Ready
// force reload when `asynchronous` changes
onAsynchronousChanged: {
const tmp = storeSettings.selected
storeSettings.selected = ""
storeSettings.selected = tmp
active = false
active = true
}
}
@ -85,9 +103,8 @@ ApplicationWindow {
}
Settings {
id: storeSettings
property string selected: ""
property bool loadAsynchronously: false
property alias currentPage: root.currentPage
property alias loadAsynchronously: loadAsyncCheckBox.checked
property alias darkMode: darkModeCheckBox.checked
}
}

View File

@ -1,8 +1,5 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import StatusQ.Popups.Dialog 0.1
import AppLayouts.CommunitiesPortal 1.0
import AppLayouts.CommunitiesPortal.stores 1.0
@ -69,7 +66,7 @@ SplitView {
logsView.logText: logs.logText
Row {
Text {
Label {
anchors.verticalCenter: parent.verticalCenter
text: "number of communities:"
}
@ -84,12 +81,10 @@ SplitView {
}
}
Control {
Pane {
SplitView.minimumWidth: 300
SplitView.preferredWidth: 300
font.pixelSize: 13
CommunitiesPortalModelEditor {
anchors.fill: parent
model: mockedModel

View File

@ -8,7 +8,7 @@ ListView {
id: root
spacing: 25
ScrollBar.vertical: ScrollBar { }
ScrollBar.vertical: ScrollBar { x: root.width }
ImageSelectPopup {
id: iconSelector
@ -46,152 +46,141 @@ ListView {
}
}
delegate: Rectangle {
width: parent.width
height: column.implicitHeight
delegate: ColumnLayout {
width: ListView.view.width
ColumnLayout {
id: column
Label {
Layout.fillWidth: true
text: "community id: " + model.communityId
font.weight: Font.Bold
}
width: parent.width
spacing: 2
TextField {
Layout.fillWidth: true
text: model.name
onTextChanged: model.name = text
}
TextField {
Layout.fillWidth: true
text: model.description
onTextChanged: model.description = text
}
Flow {
Layout.fillWidth: true
CheckBox {
text: "featured"
checked: model.featured
onToggled: model.featured = checked
}
CheckBox {
text: "available"
checked: model.available
onToggled: model.available = checked
}
CheckBox {
text: "loaded"
checked: model.loaded
onToggled: model.loaded = checked
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 50
Rectangle {
border.color: 'gray'
Layout.fillWidth: true
Layout.fillHeight: true
Image {
anchors.fill: parent
anchors.margins: 1
fillMode: Image.PreserveAspectFit
source: model.icon
}
MouseArea {
anchors.fill: parent
onClicked: {
iconSelector.open()
StorybookUtils.singleShotConnection(iconSelector.selected, icon => {
model.icon = icon
iconSelector.close()
})
}
}
}
Rectangle {
border.color: 'gray'
Layout.fillWidth: true
Layout.fillHeight: true
Image {
anchors.fill: parent
anchors.margins: 1
fillMode: Image.PreserveAspectFit
source: model.banner
}
MouseArea {
anchors.fill: parent
onClicked: {
bannerSelector.open()
StorybookUtils.singleShotConnection(bannerSelector.selected, banner => {
model.banner = banner
bannerSelector.close()
})
}
}
}
}
TextField {
Layout.fillWidth: true
maximumLength: 1024 * 1024 * 1024
text: model.icon
onTextChanged: model.icon = text
}
TextField {
Layout.fillWidth: true
maximumLength: 1024 * 1024 * 1024
text: model.banner
onTextChanged: model.banner = text
}
Row {
Label {
text: "community id: " + model.communityId
font.weight: Font.Bold
anchors.verticalCenter: parent.verticalCenter
text: "members:\t"
}
TextField {
Layout.fillWidth: true
text: model.name
onTextChanged: model.name = text
SpinBox {
editable: true
height: 30
from: 0; to: 10 * 1000 * 1000
value: model.members
onValueChanged: model.members = value
}
}
Row {
Label {
anchors.verticalCenter: parent.verticalCenter
text: "popularity:\t"
}
TextField {
Layout.fillWidth: true
text: model.description
onTextChanged: model.description = text
}
Flow {
Layout.fillWidth: true
CheckBox {
text: "featured"
checked: model.featured
onToggled: model.featured = checked
}
CheckBox {
text: "available"
checked: model.available
onToggled: model.available = checked
}
CheckBox {
text: "loaded"
checked: model.loaded
onToggled: model.loaded = checked
}
}
RowLayout {
Layout.fillWidth: true
Layout.preferredHeight: 50
Rectangle {
border.color: 'gray'
Layout.preferredWidth: root.width / 2
Layout.fillHeight: true
Image {
anchors.fill: parent
anchors.margins: 1
fillMode: Image.PreserveAspectFit
source: model.icon
}
MouseArea {
anchors.fill: parent
onClicked: {
iconSelector.open()
StorybookUtils.singleShotConnection(iconSelector.selected, icon => {
model.icon = icon
iconSelector.close()
})
}
}
}
Rectangle {
border.color: 'gray'
Layout.preferredWidth: root.width / 2
Layout.fillHeight: true
Image {
anchors.fill: parent
anchors.margins: 1
fillMode: Image.PreserveAspectFit
source: model.banner
}
MouseArea {
anchors.fill: parent
onClicked: {
bannerSelector.open()
StorybookUtils.singleShotConnection(bannerSelector.selected, banner => {
model.banner = banner
bannerSelector.close()
})
}
}
}
}
TextField {
Layout.fillWidth: true
maximumLength: 1024 * 1024 * 1024
text: model.icon
onTextChanged: model.icon = text
}
TextField {
Layout.fillWidth: true
maximumLength: 1024 * 1024 * 1024
text: model.banner
onTextChanged: model.banner = text
}
Row {
spacing: 4
Label {
anchors.verticalCenter: parent.verticalCenter
text: "members:\t"
}
SpinBox {
editable: true
height: 30
from: 0; to: 10 * 1000 * 1000
value: model.members
onValueChanged: model.members = value
}
}
Row {
spacing: 4
Label {
anchors.verticalCenter: parent.verticalCenter
text: "popularity:\t"
}
SpinBox {
editable: true
height: 30
from: 0; to: 10 * 1000 * 1000
value: model.popularity
onValueChanged: model.popularity = value
}
SpinBox {
editable: true
height: 30
from: 0; to: 10 * 1000 * 1000
value: model.popularity
onValueChanged: model.popularity = value
}
}
}

View File

@ -1,6 +1,5 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
import QtQuick.Layouts 1.14
import AppLayouts.Onboarding.views 1.0
import AppLayouts.Onboarding.stores 1.0
@ -100,8 +99,6 @@ SplitView {
SplitView.minimumWidth: 300
SplitView.preferredWidth: 300
font.pixelSize: 13
// model editor will go here
}
}

View File

@ -4,6 +4,7 @@
<file>Storybook/Logs.qml</file>
<file>Storybook/LogsAndControlsPanel.qml</file>
<file>Storybook/LogsView.qml</file>
<file>Storybook/PagesList.qml</file>
<file>Storybook/StorybookUtils.qml</file>
<file>Storybook/qmldir</file>
<file>main.qml</file>