From 1dd30e5c285d71d66b985b6813d17d8778f6bc24 Mon Sep 17 00:00:00 2001 From: Ryan Hughes Date: Mon, 18 May 2026 00:22:50 -0400 Subject: [PATCH] Extract qs.Ui.TextField, migrate wifi passphrase + settings + dynamic form --- default/quickshell/omarchy-shell/Ui/README.md | 1 + .../quickshell/omarchy-shell/Ui/TextField.qml | 49 +++++++++++++++ default/quickshell/omarchy-shell/Ui/qmldir | 1 + .../plugins/bar/widgets/networkPanel.qml | 22 ++----- .../plugins/dev-gallery/GalleryPanel.qml | 60 +++++++++++++++++++ .../plugins/settings/SettingsPanel.qml | 21 +------ .../ui/settings/DynamicSettingsForm.qml | 19 +----- 7 files changed, 120 insertions(+), 53 deletions(-) create mode 100644 default/quickshell/omarchy-shell/Ui/TextField.qml diff --git a/default/quickshell/omarchy-shell/Ui/README.md b/default/quickshell/omarchy-shell/Ui/README.md index 52edbc3e..c0c24860 100644 --- a/default/quickshell/omarchy-shell/Ui/README.md +++ b/default/quickshell/omarchy-shell/Ui/README.md @@ -57,6 +57,7 @@ Grouped by what they're for, not alphabetically. | `CursorPill` | `PillButton` that participates in a panel's single-cursor model. Adds a `hovered(bool)` signal so the panel can update its cursor state on mouse enter/leave. Use for DNS-pill / header-pill / segmented-choice patterns. | | `ChoiceButton` | A single button in a mutually-exclusive choice group (segmented control). `selected` uses accent fill+border; focus uses `Style.focusBorderColor` so keyboard nav reads differently from selection. | | `Toggle` | Title + description + switch. Click anywhere on the row to flip; caller updates `checked` in response. | +| `TextField` | Single-line input. Inherits from Qt Quick Controls `TextField` so all of its base API (text, placeholderText, accepted, validator, ...) is available. Adds `password: bool`, `foreground` / `accent` / `selectionTint` color overrides, and `horizontalPadding` / `verticalPadding` size knobs. Focus styling uses `Style.focusBorderColor` to match `Toggle` and `ChoiceButton`. | | `PanelActionButton` | 22×22 right-edge action button (confirm, forget, unpair). `hoverColor` swaps between default foreground tint and urgent (red) tint. | | `PanelSlider` | Volume/progress slider. Drag, click track, or wheel. `moved(value)` fires per change, `released(value)` once at end. (Named to avoid colliding with `QtQuick.Controls.Slider`.) | | `WidgetButton` | Bar widget chrome — for the strip itself, not for inside panels. | diff --git a/default/quickshell/omarchy-shell/Ui/TextField.qml b/default/quickshell/omarchy-shell/Ui/TextField.qml new file mode 100644 index 00000000..f66b7a9f --- /dev/null +++ b/default/quickshell/omarchy-shell/Ui/TextField.qml @@ -0,0 +1,49 @@ +import QtQuick +import QtQuick.Controls +import qs.Commons + +// Single-line text input with the kit's focus + selection styling. Inherits +// from Qt Quick Controls TextField so the underlying type's API (text, +// placeholderText, accepted, editingFinished, validator, ...) is available +// to callers without re-exposing each property. +// +// Defaults bind to qs.Commons.Color so a caller with no theme overrides +// just works; foreground / accent / selectionTint can be overridden per +// instance. Focus styling uses Style.focusBorderColor (the same accent +// ring Toggle and ChoiceButton paint) so keyboard cursor and form-focus +// chrome stay consistent across the shell. +// +// Sizing is driven by font.pixelSize + verticalPadding. The default 30px +// implicitHeight fits dialog forms; inline callers (wifi's row-embedded +// passphrase prompt) drop verticalPadding to match a 22-26px row. +TextField { + id: root + + property color foreground: Color.foreground + property color accent: Color.accent + property color selectionTint: Qt.rgba(foreground.r, foreground.g, foreground.b, 0.35) + property bool password: false + property real horizontalPadding: 10 + property real verticalPadding: 7 + + echoMode: password ? TextInput.Password : TextInput.Normal + color: foreground + selectionColor: selectionTint + selectedTextColor: foreground + placeholderTextColor: Qt.darker(foreground, 1.6) + + leftPadding: horizontalPadding + rightPadding: horizontalPadding + topPadding: verticalPadding + bottomPadding: verticalPadding + + background: Rectangle { + color: Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, + root.activeFocus ? 0.08 : 0.04) + border.color: root.activeFocus + ? Style.focusBorderColor + : Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, 0.18) + border.width: root.activeFocus ? Style.focusBorderWidth : 1 + radius: Style.cornerRadius + } +} diff --git a/default/quickshell/omarchy-shell/Ui/qmldir b/default/quickshell/omarchy-shell/Ui/qmldir index c1ede27b..5d168b43 100644 --- a/default/quickshell/omarchy-shell/Ui/qmldir +++ b/default/quickshell/omarchy-shell/Ui/qmldir @@ -12,5 +12,6 @@ PanelSlider 1.0 PanelSlider.qml PanelToolTip 1.0 PanelToolTip.qml PillButton 1.0 PillButton.qml PopupCard 1.0 PopupCard.qml +TextField 1.0 TextField.qml Toggle 1.0 Toggle.qml WidgetButton 1.0 WidgetButton.qml diff --git a/default/quickshell/omarchy-shell/plugins/bar/widgets/networkPanel.qml b/default/quickshell/omarchy-shell/plugins/bar/widgets/networkPanel.qml index 808689f0..add0543d 100644 --- a/default/quickshell/omarchy-shell/plugins/bar/widgets/networkPanel.qml +++ b/default/quickshell/omarchy-shell/plugins/bar/widgets/networkPanel.qml @@ -1090,29 +1090,15 @@ iwctl known-networks list 2>/dev/null \\ anchors.right: connectPwBtn.left anchors.verticalCenter: parent.verticalCenter anchors.rightMargin: 6 - echoMode: TextInput.Password + password: true placeholderText: "Passphrase" font.family: root.bar.fontFamily font.pixelSize: 12 - color: root.bar.foreground - selectionColor: Qt.rgba(root.bar.foreground.r, root.bar.foreground.g, root.bar.foreground.b, 0.35) - selectedTextColor: root.bar.foreground - placeholderTextColor: Qt.darker(root.bar.foreground, 1.6) - leftPadding: 8 - rightPadding: 8 - topPadding: 6 - bottomPadding: 6 + foreground: root.bar.foreground + horizontalPadding: 8 + verticalPadding: 6 enabled: !row.isBusy - background: Rectangle { - color: Qt.rgba(root.bar.foreground.r, root.bar.foreground.g, root.bar.foreground.b, pwField.activeFocus ? 0.10 : 0.05) - border.color: pwField.activeFocus - ? Qt.rgba(root.bar.foreground.r, root.bar.foreground.g, root.bar.foreground.b, 0.45) - : Qt.rgba(root.bar.foreground.r, root.bar.foreground.g, root.bar.foreground.b, 0.20) - border.width: 1 - radius: 4 - } - onAccepted: { if (!root.busy && row.net && text.length > 0) root.connectWithPassphrase(row.net.ssid, text) } diff --git a/default/quickshell/omarchy-shell/plugins/dev-gallery/GalleryPanel.qml b/default/quickshell/omarchy-shell/plugins/dev-gallery/GalleryPanel.qml index a541f1af..710eefa3 100644 --- a/default/quickshell/omarchy-shell/plugins/dev-gallery/GalleryPanel.qml +++ b/default/quickshell/omarchy-shell/plugins/dev-gallery/GalleryPanel.qml @@ -699,6 +699,66 @@ Item { } } + // ---- TextField ----------------------------------------------------- + Column { + width: parent.width + spacing: 8 + + Text { + text: "TextField" + color: root.foreground + font.family: root.fontFamily + font.pixelSize: 13 + font.bold: true + } + Text { + text: "Single-line input. Inherits Qt Quick Controls TextField, swaps in the kit's focus chrome and selection styling. Toggle `password: true` for masked entry." + color: Qt.darker(root.foreground, 1.5) + font.family: root.fontFamily + font.pixelSize: 10 + width: parent.width + wrapMode: Text.WordWrap + } + + Rectangle { + width: parent.width + implicitHeight: tfCol.implicitHeight + 24 + color: Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, 0.04) + radius: 6 + border.color: Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, 0.10) + border.width: 1 + + Column { + id: tfCol + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 14 + anchors.rightMargin: 14 + spacing: 10 + + TextField { + width: parent.width + placeholderText: "Type something" + foreground: root.foreground + accent: root.accent + font.family: root.fontFamily + font.pixelSize: 12 + } + + TextField { + width: parent.width + password: true + placeholderText: "Password" + foreground: root.foreground + accent: root.accent + font.family: root.fontFamily + font.pixelSize: 12 + } + } + } + } + // ---- Toggle -------------------------------------------------------- Column { width: parent.width diff --git a/default/quickshell/omarchy-shell/plugins/settings/SettingsPanel.qml b/default/quickshell/omarchy-shell/plugins/settings/SettingsPanel.qml index 74f3a088..dd961ec0 100644 --- a/default/quickshell/omarchy-shell/plugins/settings/SettingsPanel.qml +++ b/default/quickshell/omarchy-shell/plugins/settings/SettingsPanel.qml @@ -1210,28 +1210,13 @@ Item { width: parent ? parent.width : 0 component CalendarField: TextField { - id: calField property string fieldKey: "" + width: parent.width + foreground: root.foreground + accent: root.accent font.family: root.fontFamily font.pixelSize: 12 - width: parent.width - color: root.foreground - selectionColor: Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, 0.35) - selectedTextColor: root.foreground - placeholderTextColor: Qt.darker(root.foreground, 1.6) - leftPadding: 10 - rightPadding: 10 - topPadding: 7 - bottomPadding: 7 onEditingFinished: if (fieldKey) calForm.fieldChanged(fieldKey, text) - background: Rectangle { - color: Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, - calField.activeFocus ? 0.08 : 0.04) - border.color: calField.activeFocus - ? Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, 0.4) - : Qt.rgba(root.foreground.r, root.foreground.g, root.foreground.b, 0.18) - border.width: 1 - } } Text { diff --git a/default/quickshell/omarchy-shell/ui/settings/DynamicSettingsForm.qml b/default/quickshell/omarchy-shell/ui/settings/DynamicSettingsForm.qml index e550ad97..658fd8a1 100644 --- a/default/quickshell/omarchy-shell/ui/settings/DynamicSettingsForm.qml +++ b/default/quickshell/omarchy-shell/ui/settings/DynamicSettingsForm.qml @@ -1,6 +1,7 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts +import qs.Ui // Generic schema-driven settings form. The host panel passes: // - schema: array of { key, label, type, defaultValue?, options?, min?, max?, step?, description? } @@ -83,30 +84,14 @@ Column { Component { id: stringField TextField { - id: stringControl property string fieldKey: "" property var field: ({}) width: parent.width + foreground: root.foregroundColor font.family: root.fontFamilyName font.pixelSize: 12 - color: root.foregroundColor - selectionColor: Qt.rgba(root.foregroundColor.r, root.foregroundColor.g, root.foregroundColor.b, 0.35) - selectedTextColor: root.foregroundColor - placeholderTextColor: Qt.darker(root.foregroundColor, 1.6) - leftPadding: 10 - rightPadding: 10 - topPadding: 7 - bottomPadding: 7 text: root.currentValue(field) === undefined ? "" : String(root.currentValue(field)) onEditingFinished: if (fieldKey) root.fieldChanged(fieldKey, text) - background: Rectangle { - color: Qt.rgba(root.foregroundColor.r, root.foregroundColor.g, root.foregroundColor.b, - stringControl.activeFocus ? 0.08 : 0.04) - border.color: stringControl.activeFocus - ? Qt.rgba(root.foregroundColor.r, root.foregroundColor.g, root.foregroundColor.b, 0.4) - : Qt.rgba(root.foregroundColor.r, root.foregroundColor.g, root.foregroundColor.b, 0.18) - border.width: 1 - } } }