chore(StoryBook): add Colors page
- gives an overview of all the `Theme.palette.foo` colors - the color name/code can be copied to clipboard - light/dark variant supported via storybook's "Dark mode" switch - integrated search (both the color name and value)
This commit is contained in:
parent
26b875ea16
commit
bbd0e71fd6
|
@ -0,0 +1,278 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
import Storybook 1.0
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
orientation: Qt.Vertical
|
||||
|
||||
component ColorRectangle: Rectangle {
|
||||
id: colorRectangle
|
||||
property alias text: textLabel.text
|
||||
|
||||
implicitWidth: 120
|
||||
implicitHeight: 60
|
||||
Column {
|
||||
anchors.centerIn: parent
|
||||
Row {
|
||||
spacing: 4
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Text {
|
||||
id: textLabel
|
||||
}
|
||||
ToolButton {
|
||||
focusPolicy: Qt.NoFocus
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 16
|
||||
height: 16
|
||||
padding: 0
|
||||
text: "📋"
|
||||
font.pixelSize: 10
|
||||
onClicked: QClipboardProxy.copyTextToClipboard(textLabel.text)
|
||||
ToolTip.text: "Copy color name"
|
||||
ToolTip.visible: hovered
|
||||
}
|
||||
}
|
||||
Row {
|
||||
spacing: 4
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
Text {
|
||||
id: colorLabel
|
||||
color: textLabel.color
|
||||
text: colorRectangle.color.toString()
|
||||
}
|
||||
ToolButton {
|
||||
focusPolicy: Qt.NoFocus
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 16
|
||||
height: 16
|
||||
padding: 0
|
||||
text: "📋"
|
||||
font.pixelSize: 10
|
||||
onClicked: QClipboardProxy.copyTextToClipboard(colorLabel.text)
|
||||
ToolTip.text: "Copy color value"
|
||||
ToolTip.visible: hovered
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component ColorFlow: ColumnLayout {
|
||||
id: colorFlow
|
||||
|
||||
property string title
|
||||
property var model
|
||||
|
||||
ListModel {
|
||||
id: listModel
|
||||
Component.onCompleted: {
|
||||
append(Object.entries(colorFlow.model))
|
||||
}
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.topMargin: 8
|
||||
//visible: colorRepeater.count
|
||||
font.weight: Font.Medium
|
||||
text: "%1 (%2)".arg(colorFlow.title).arg(colorRepeater.count)
|
||||
}
|
||||
Flow {
|
||||
Layout.preferredWidth: scrollview.availableWidth
|
||||
spacing: 5
|
||||
|
||||
Repeater {
|
||||
id: colorRepeater
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: listModel
|
||||
proxyRoles: [
|
||||
ExpressionRole {
|
||||
name: "name"
|
||||
expression: model[0]
|
||||
},
|
||||
ExpressionRole {
|
||||
name: "color"
|
||||
expression: model[1]
|
||||
}
|
||||
]
|
||||
filters: FastExpressionFilter {
|
||||
expression: {
|
||||
searchField.searchText
|
||||
return (!!model.name && model.name.toLowerCase().includes(searchField.searchText)) ||
|
||||
(!!model.color && model.color.toLowerCase().includes(searchField.searchText))
|
||||
}
|
||||
enabled: searchField.searchText !== ""
|
||||
expectedRoles: ["name", "color"]
|
||||
}
|
||||
}
|
||||
delegate: ColorRectangle {
|
||||
text: model.name
|
||||
color: model.color
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: searchField.forceActiveFocus()
|
||||
|
||||
ScrollView {
|
||||
id: scrollview
|
||||
contentWidth: availableWidth
|
||||
SplitView.fillHeight: true
|
||||
padding: 8
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
RowLayout {
|
||||
Label {
|
||||
text: "Search"
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
TextField {
|
||||
readonly property string searchText: text.toLowerCase()
|
||||
id: searchField
|
||||
}
|
||||
ToolButton {
|
||||
focusPolicy: Qt.NoFocus
|
||||
text: "❌"
|
||||
enabled: searchField.searchText !== ""
|
||||
onClicked: searchField.clear()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Base"
|
||||
model: {
|
||||
"baseColor1": Theme.palette.baseColor1.toString(),
|
||||
"baseColor2": Theme.palette.baseColor2.toString(),
|
||||
"baseColor3": Theme.palette.baseColor3.toString(),
|
||||
"baseColor4": Theme.palette.baseColor4.toString(),
|
||||
"baseColor5": Theme.palette.baseColor5.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Primary"
|
||||
model: {
|
||||
"primaryColor1": Theme.palette.primaryColor1.toString(),
|
||||
"primaryColor2": Theme.palette.primaryColor2.toString(),
|
||||
"primaryColor3": Theme.palette.primaryColor3.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Danger"
|
||||
model: {
|
||||
"dangerColor1": Theme.palette.dangerColor1.toString(),
|
||||
"dangerColor2": Theme.palette.dangerColor2.toString(),
|
||||
"dangerColor3": Theme.palette.dangerColor3.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Warning"
|
||||
model: {
|
||||
"warningColor1": Theme.palette.warningColor1.toString(),
|
||||
"warningColor2": Theme.palette.warningColor2.toString(),
|
||||
"warningColor3": Theme.palette.warningColor3.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Success"
|
||||
model: {
|
||||
"successColor1": Theme.palette.successColor1.toString(),
|
||||
"successColor2": Theme.palette.successColor2.toString(),
|
||||
"successColor3": Theme.palette.successColor3.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Direct"
|
||||
model: {
|
||||
"directColor1": Theme.palette.directColor1.toString(),
|
||||
"directColor2": Theme.palette.directColor2.toString(),
|
||||
"directColor3": Theme.palette.directColor3.toString(),
|
||||
"directColor4": Theme.palette.directColor4.toString(),
|
||||
"directColor5": Theme.palette.directColor5.toString(),
|
||||
"directColor6": Theme.palette.directColor6.toString(),
|
||||
"directColor7": Theme.palette.directColor7.toString(),
|
||||
"directColor8": Theme.palette.directColor8.toString(),
|
||||
"directColor9": Theme.palette.directColor9.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Indirect"
|
||||
model: {
|
||||
"indirectColor1": Theme.palette.indirectColor1.toString(),
|
||||
"indirectColor2": Theme.palette.indirectColor2.toString(),
|
||||
"indirectColor3": Theme.palette.indirectColor3.toString(),
|
||||
"indirectColor4": Theme.palette.indirectColor4.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Mention"
|
||||
model: {
|
||||
"mentionColor1": Theme.palette.mentionColor1.toString(),
|
||||
"mentionColor2": Theme.palette.mentionColor2.toString(),
|
||||
"mentionColor3": Theme.palette.mentionColor3.toString(),
|
||||
"mentionColor4": Theme.palette.mentionColor4.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Pin"
|
||||
model: {
|
||||
"pinColor1": Theme.palette.pinColor1.toString(),
|
||||
"pinColor2": Theme.palette.pinColor2.toString(),
|
||||
"pinColor3": Theme.palette.pinColor3.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Misc"
|
||||
model: {
|
||||
"miscColor1": Theme.palette.miscColor1.toString(),
|
||||
"miscColor2": Theme.palette.miscColor2.toString(),
|
||||
"miscColor3": Theme.palette.miscColor3.toString(),
|
||||
"miscColor4": Theme.palette.miscColor4.toString(),
|
||||
"miscColor5": Theme.palette.miscColor5.toString(),
|
||||
"miscColor6": Theme.palette.miscColor6.toString(),
|
||||
"miscColor7": Theme.palette.miscColor7.toString(),
|
||||
"miscColor8": Theme.palette.miscColor8.toString(),
|
||||
"miscColor9": Theme.palette.miscColor9.toString(),
|
||||
"miscColor10": Theme.palette.miscColor10.toString(),
|
||||
"miscColor11": Theme.palette.miscColor11.toString(),
|
||||
"miscColor12": Theme.palette.miscColor12.toString()
|
||||
}
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "User customization"
|
||||
model: Theme.palette.userCustomizationColors
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Identicon ring colors"
|
||||
model: Theme.palette.identiconRingColors
|
||||
}
|
||||
|
||||
ColorFlow {
|
||||
title: "Status colors"
|
||||
model: StatusColors.colors
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Core
|
|
@ -54,6 +54,7 @@ public:
|
|||
|
||||
Q_INVOKABLE bool isValidImageUrl(const QUrl &url, const QStringList &acceptedExtensions) const;
|
||||
Q_INVOKABLE qint64 getFileSize(const QUrl &url) const;
|
||||
Q_INVOKABLE void copyTextToClipboard(const QString& text);
|
||||
|
||||
signals:
|
||||
void contentChanged();
|
||||
|
|
|
@ -59,7 +59,7 @@ QString QClipboardProxy::imageBase64() const
|
|||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
img.save(&buffer, "JPG");
|
||||
return QStringLiteral("data:image/jpeg;base64,") + byteArray.toBase64();
|
||||
return QByteArrayLiteral("data:image/jpeg;base64,") + byteArray.toBase64();
|
||||
}
|
||||
|
||||
bool QClipboardProxy::hasUrls() const
|
||||
|
@ -87,3 +87,8 @@ qint64 QClipboardProxy::getFileSize(const QUrl& url) const
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QClipboardProxy::copyTextToClipboard(const QString &text)
|
||||
{
|
||||
m_clipboard->setText(text);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue