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:
parent
057d0c565e
commit
5537f5edd7
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,4 +2,5 @@ ImageSelectPopup 1.0 ImageSelectPopup.qml
|
||||||
Logs 1.0 Logs.qml
|
Logs 1.0 Logs.qml
|
||||||
LogsAndControlsPanel 1.0 LogsAndControlsPanel.qml
|
LogsAndControlsPanel 1.0 LogsAndControlsPanel.qml
|
||||||
LogsView 1.0 LogsView.qml
|
LogsView 1.0 LogsView.qml
|
||||||
|
PagesList 1.0 PagesList.qml
|
||||||
singleton StorybookUtils 1.0 StorybookUtils.qml
|
singleton StorybookUtils 1.0 StorybookUtils.qml
|
||||||
|
|
|
@ -1,63 +1,82 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
import StatusQ.Core 0.1
|
|
||||||
import StatusQ.Components 0.1
|
|
||||||
import StatusQ.Layout 0.1
|
|
||||||
|
|
||||||
import Qt.labs.settings 1.0
|
import Qt.labs.settings 1.0
|
||||||
|
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import Storybook 1.0
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
id: rootWindow
|
id: root
|
||||||
|
|
||||||
width: 1450
|
width: 1450
|
||||||
height: 840
|
height: 840
|
||||||
visible: true
|
visible: true
|
||||||
|
|
||||||
StatusSectionLayout {
|
property string currentPage
|
||||||
id: mainPageView
|
|
||||||
|
|
||||||
anchors.fill: parent
|
font.pixelSize: 13
|
||||||
showHeader: false
|
|
||||||
|
|
||||||
function page(name, fillPage) {
|
ListModel {
|
||||||
viewLoader.source = Qt.resolvedUrl("./pages/" + name + "Page.qml");
|
id: pagesModel
|
||||||
storeSettings.selected = viewLoader.source
|
|
||||||
|
ListElement {
|
||||||
|
title: "CommunitiesPortalLayout"
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
title: "LoginView"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
leftPanel: StatusScrollView {
|
SplitView {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.topMargin: 48
|
|
||||||
|
|
||||||
Column {
|
ColumnLayout {
|
||||||
spacing: 0
|
SplitView.preferredWidth: 240
|
||||||
|
|
||||||
CheckBox {
|
CheckBox {
|
||||||
text: "Load asynchronously"
|
id: loadAsyncCheckBox
|
||||||
checked: storeSettings.loadAsynchronously
|
|
||||||
|
|
||||||
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 {
|
PagesList {
|
||||||
title: "CommunitiesPortalLayout"
|
anchors.fill: parent
|
||||||
selected: viewLoader.source.toString().includes(title)
|
|
||||||
onClicked: mainPageView.page(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
StatusNavigationListItem {
|
currentPage: root.currentPage
|
||||||
title: "LoginView"
|
model: pagesModel
|
||||||
selected: viewLoader.source.toString().includes(title)
|
|
||||||
onClicked: mainPageView.page(title);
|
onPageSelected: root.currentPage = page
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
centerPanel: Item {
|
Item {
|
||||||
anchors.fill: parent
|
SplitView.fillWidth: true
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: viewLoader
|
id: viewLoader
|
||||||
|
@ -65,15 +84,14 @@ ApplicationWindow {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
source: storeSettings.selected
|
source: Qt.resolvedUrl(`./pages/${root.currentPage}Page.qml`)
|
||||||
asynchronous: storeSettings.loadAsynchronously
|
asynchronous: loadAsyncCheckBox.checked
|
||||||
visible: status === Loader.Ready
|
visible: status === Loader.Ready
|
||||||
|
|
||||||
// force reload when `asynchronous` changes
|
// force reload when `asynchronous` changes
|
||||||
onAsynchronousChanged: {
|
onAsynchronousChanged: {
|
||||||
const tmp = storeSettings.selected
|
active = false
|
||||||
storeSettings.selected = ""
|
active = true
|
||||||
storeSettings.selected = tmp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +103,8 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
id: storeSettings
|
property alias currentPage: root.currentPage
|
||||||
|
property alias loadAsynchronously: loadAsyncCheckBox.checked
|
||||||
property string selected: ""
|
property alias darkMode: darkModeCheckBox.checked
|
||||||
property bool loadAsynchronously: false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 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 1.0
|
||||||
import AppLayouts.CommunitiesPortal.stores 1.0
|
import AppLayouts.CommunitiesPortal.stores 1.0
|
||||||
|
@ -69,7 +66,7 @@ SplitView {
|
||||||
logsView.logText: logs.logText
|
logsView.logText: logs.logText
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
Text {
|
Label {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
text: "number of communities:"
|
text: "number of communities:"
|
||||||
}
|
}
|
||||||
|
@ -84,12 +81,10 @@ SplitView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Control {
|
Pane {
|
||||||
SplitView.minimumWidth: 300
|
SplitView.minimumWidth: 300
|
||||||
SplitView.preferredWidth: 300
|
SplitView.preferredWidth: 300
|
||||||
|
|
||||||
font.pixelSize: 13
|
|
||||||
|
|
||||||
CommunitiesPortalModelEditor {
|
CommunitiesPortalModelEditor {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: mockedModel
|
model: mockedModel
|
||||||
|
|
|
@ -8,7 +8,7 @@ ListView {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
spacing: 25
|
spacing: 25
|
||||||
ScrollBar.vertical: ScrollBar { }
|
ScrollBar.vertical: ScrollBar { x: root.width }
|
||||||
|
|
||||||
ImageSelectPopup {
|
ImageSelectPopup {
|
||||||
id: iconSelector
|
id: iconSelector
|
||||||
|
@ -46,152 +46,141 @@ ListView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delegate: Rectangle {
|
delegate: ColumnLayout {
|
||||||
width: parent.width
|
width: ListView.view.width
|
||||||
height: column.implicitHeight
|
|
||||||
|
|
||||||
ColumnLayout {
|
Label {
|
||||||
id: column
|
Layout.fillWidth: true
|
||||||
|
text: "community id: " + model.communityId
|
||||||
|
font.weight: Font.Bold
|
||||||
|
}
|
||||||
|
|
||||||
width: parent.width
|
TextField {
|
||||||
spacing: 2
|
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 {
|
Label {
|
||||||
text: "community id: " + model.communityId
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
font.weight: Font.Bold
|
text: "members:\t"
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
SpinBox {
|
||||||
Layout.fillWidth: true
|
editable: true
|
||||||
text: model.name
|
height: 30
|
||||||
onTextChanged: model.name = text
|
from: 0; to: 10 * 1000 * 1000
|
||||||
|
value: model.members
|
||||||
|
onValueChanged: model.members = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
Label {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: "popularity:\t"
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
SpinBox {
|
||||||
Layout.fillWidth: true
|
editable: true
|
||||||
text: model.description
|
height: 30
|
||||||
onTextChanged: model.description = text
|
from: 0; to: 10 * 1000 * 1000
|
||||||
}
|
value: model.popularity
|
||||||
|
onValueChanged: model.popularity = value
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
import QtQuick.Layouts 1.14
|
|
||||||
|
|
||||||
import AppLayouts.Onboarding.views 1.0
|
import AppLayouts.Onboarding.views 1.0
|
||||||
import AppLayouts.Onboarding.stores 1.0
|
import AppLayouts.Onboarding.stores 1.0
|
||||||
|
@ -100,8 +99,6 @@ SplitView {
|
||||||
SplitView.minimumWidth: 300
|
SplitView.minimumWidth: 300
|
||||||
SplitView.preferredWidth: 300
|
SplitView.preferredWidth: 300
|
||||||
|
|
||||||
font.pixelSize: 13
|
|
||||||
|
|
||||||
// model editor will go here
|
// model editor will go here
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
<file>Storybook/Logs.qml</file>
|
<file>Storybook/Logs.qml</file>
|
||||||
<file>Storybook/LogsAndControlsPanel.qml</file>
|
<file>Storybook/LogsAndControlsPanel.qml</file>
|
||||||
<file>Storybook/LogsView.qml</file>
|
<file>Storybook/LogsView.qml</file>
|
||||||
|
<file>Storybook/PagesList.qml</file>
|
||||||
<file>Storybook/StorybookUtils.qml</file>
|
<file>Storybook/StorybookUtils.qml</file>
|
||||||
<file>Storybook/qmldir</file>
|
<file>Storybook/qmldir</file>
|
||||||
<file>main.qml</file>
|
<file>main.qml</file>
|
||||||
|
|
Loading…
Reference in New Issue