feat(ui): add browser-local Control UI text size setting · openclaw/openclaw@52370c5
BunsDev
·
2026-05-14
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -117,6 +117,7 @@ Docs: https://docs.openclaw.ai
|
117 | 117 | |
118 | 118 | ### Changes |
119 | 119 | |
| 120 | +- Control UI: add a browser-local Text size setting in Appearance and Quick Settings, scaling chat and dense UI text while keeping inputs above the mobile Safari focus-zoom threshold. Fixes #8547. Thanks @BunsDev. |
120 | 121 | - Docs: add a dedicated ds4 provider page with local DeepSeek V4 Flash config, on-demand startup, context sizing, and live verification steps. |
121 | 122 | - Release validation: add a package-installed Docker user-journey lane that verifies onboarding, mocked model setup, external plugin install/uninstall, ClickClack outbound/inbound messaging, Gateway restart survival, and doctor. |
122 | 123 | - Release validation: add package-installed Docker lanes for real TTY onboarding, media and memory persistence, published-package upgrade journeys, and local marketplace plugin install/update/uninstall coverage. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -89,6 +89,8 @@ Docs translations are generated for the same non-English locale set, but the doc
|
89 | 89 | |
90 | 90 | The Appearance panel keeps the built-in Claw, Knot, and Dash themes, plus one browser-local tweakcn import slot. To import a theme, open [tweakcn editor](https://tweakcn.com/editor/theme), choose or create a theme, click **Share**, and paste the copied theme link into Appearance. The importer also accepts `https://tweakcn.com/r/themes/<id>` registry URLs, editor URLs like `https://tweakcn.com/editor/theme?theme=amethyst-haze`, relative `/themes/<id>` paths, raw theme IDs, and default theme names such as `amethyst-haze`. |
91 | 91 | |
| 92 | +Appearance also includes a browser-local Text size setting. The setting is stored with the rest of Control UI preferences, applies to chat text, composer text, tool cards, and chat sidebars, and keeps text inputs at least 16px so mobile Safari does not auto-zoom on focus. |
| 93 | + |
92 | 94 | Imported themes are stored only in the current browser profile. They are not written to gateway config and do not sync across devices. Replacing the imported theme updates the one local slot; clearing it switches the active theme back to Claw if the imported theme was selected. |
93 | 95 | |
94 | 96 | ## What it can do (today) |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -85,6 +85,13 @@
|
85 | 85 | "JetBrains Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, monospace; |
86 | 86 | --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; |
87 | 87 | --font-display: var(--font-body); |
| 88 | +--control-ui-text-scale: 1; |
| 89 | +--control-ui-text-xs: calc(11px * var(--control-ui-text-scale)); |
| 90 | +--control-ui-text-sm: calc(12px * var(--control-ui-text-scale)); |
| 91 | +--control-ui-text-md: calc(14px * var(--control-ui-text-scale)); |
| 92 | +--control-ui-text-lg: calc(16px * var(--control-ui-text-scale)); |
| 93 | +--control-ui-input-text-size: max(16px, calc(14px * var(--control-ui-text-scale))); |
| 94 | +--chat-text-size: var(--control-ui-text-md); |
88 | 95 | |
89 | 96 | /* Shadows - Subtle, layered depth */ |
90 | 97 | --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -517,7 +517,7 @@
|
517 | 517 | resize: none; |
518 | 518 | white-space: pre-wrap; |
519 | 519 | font-family: var(--font-body); |
520 | | -font-size: 14px; |
| 520 | +font-size: var(--control-ui-input-text-size); |
521 | 521 | line-height: 1.45; |
522 | 522 | } |
523 | 523 | |
|
597 | 597 | border: none; |
598 | 598 | background: transparent; |
599 | 599 | color: var(--text); |
600 | | -font-size: 0.92rem; |
| 600 | +font-size: var(--control-ui-input-text-size); |
601 | 601 | font-family: inherit; |
602 | 602 | line-height: 1.4; |
603 | 603 | outline: none; |
@@ -615,7 +615,7 @@
|
615 | 615 | .agent-chat__stt-interim { |
616 | 616 | padding: 10px 14px 0; |
617 | 617 | color: var(--muted); |
618 | | -font-size: 0.82rem; |
| 618 | +font-size: var(--control-ui-text-sm); |
619 | 619 | line-height: 1.35; |
620 | 620 | overflow-wrap: anywhere; |
621 | 621 | } |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -22,4 +22,12 @@ describe("chat layout styles", () => {
|
22 | 22 | expect(css).toContain("font-size: 20px;"); |
23 | 23 | expect(css).toContain("place-items: center;"); |
24 | 24 | }); |
| 25 | + |
| 26 | +it("keeps composer text scale-driven while preserving mobile input zoom safety", () => { |
| 27 | +const css = readLayoutCss(); |
| 28 | + |
| 29 | +expect(css).toContain("font-size: var(--control-ui-input-text-size);"); |
| 30 | +expect(css).toContain(".agent-chat__composer-combobox > textarea"); |
| 31 | +expect(css).toContain(".chat-compose .chat-compose__field textarea"); |
| 32 | +}); |
25 | 33 | }); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -68,7 +68,7 @@
|
68 | 68 | |
69 | 69 | .sidebar-title { |
70 | 70 | font-weight: 600; |
71 | | -font-size: 14px; |
| 71 | +font-size: var(--control-ui-text-md); |
72 | 72 | } |
73 | 73 | |
74 | 74 | .sidebar-content { |
@@ -78,7 +78,7 @@
|
78 | 78 | } |
79 | 79 | |
80 | 80 | .sidebar-markdown { |
81 | | -font-size: 14px; |
| 81 | +font-size: var(--control-ui-text-md); |
82 | 82 | line-height: 1.6; |
83 | 83 | color: var(--text); |
84 | 84 | } |
|
123 | 123 | |
124 | 124 | .sidebar-markdown-shell__hint { |
125 | 125 | color: var(--muted); |
126 | | -font-size: 12px; |
| 126 | +font-size: var(--control-ui-text-sm); |
127 | 127 | line-height: 1.45; |
128 | 128 | } |
129 | 129 | |
|
158 | 158 | } |
159 | 159 | |
160 | 160 | .sidebar-markdown-reader.sidebar-markdown { |
161 | | -font-size: 14.5px; |
| 161 | +font-size: calc(14.5px * var(--control-ui-text-scale)); |
162 | 162 | line-height: 1.72; |
163 | 163 | } |
164 | 164 | |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -9,7 +9,7 @@
|
9 | 9 | border: 1px dashed rgba(255, 255, 255, 0.18); |
10 | 10 | background: rgba(255, 255, 255, 0.04); |
11 | 11 | color: var(--muted); |
12 | | -font-size: 12px; |
| 12 | +font-size: var(--control-ui-text-sm); |
13 | 13 | line-height: 1.4; |
14 | 14 | } |
15 | 15 | |
@@ -19,7 +19,7 @@
|
19 | 19 | } |
20 | 20 | |
21 | 21 | .chat-text { |
22 | | -font-size: 14px; |
| 22 | +font-size: var(--chat-text-size); |
23 | 23 | line-height: 1.5; |
24 | 24 | word-wrap: break-word; |
25 | 25 | overflow-wrap: break-word; |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import { describe, expect, it } from "vitest"; |
| 2 | +import { readStyleSheet } from "../../../../test/helpers/ui-style-fixtures.js"; |
| 3 | + |
| 4 | +function readTextCss(): string { |
| 5 | +return readStyleSheet("ui/src/styles/chat/text.css"); |
| 6 | +} |
| 7 | + |
| 8 | +describe("chat text styles", () => { |
| 9 | +it("uses browser-local text scale variables for message text", () => { |
| 10 | +const css = readTextCss(); |
| 11 | + |
| 12 | +expect(css).toContain("font-size: var(--chat-text-size);"); |
| 13 | +expect(css).toContain("font-size: var(--control-ui-text-sm);"); |
| 14 | +}); |
| 15 | +}); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -64,7 +64,7 @@
|
64 | 64 | align-items: center; |
65 | 65 | gap: 6px; |
66 | 66 | font-weight: 600; |
67 | | -font-size: 14px; |
| 67 | +font-size: var(--control-ui-text-md); |
68 | 68 | line-height: 1.2; |
69 | 69 | min-width: 0; |
70 | 70 | } |
|
157 | 157 | } |
158 | 158 | |
159 | 159 | .chat-tool-card__status-text { |
160 | | -font-size: 11px; |
| 160 | +font-size: var(--control-ui-text-xs); |
161 | 161 | margin-top: 10px; |
162 | 162 | } |
163 | 163 | |
164 | 164 | .chat-tool-card__detail { |
165 | | -font-size: 12px; |
| 165 | +font-size: var(--control-ui-text-sm); |
166 | 166 | color: var(--muted); |
167 | 167 | margin-top: 6px; |
168 | 168 | } |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -801,6 +801,62 @@
|
801 | 801 | color: var(--accent); |
802 | 802 | } |
803 | 803 | |
| 804 | +.settings-text-scale { |
| 805 | +display: grid; |
| 806 | +gap: 8px; |
| 807 | +} |
| 808 | + |
| 809 | +.settings-text-scale__options { |
| 810 | +display: grid; |
| 811 | +grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); |
| 812 | +gap: 8px; |
| 813 | +} |
| 814 | + |
| 815 | +.settings-text-scale__btn { |
| 816 | +display: grid; |
| 817 | +gap: 4px; |
| 818 | +justify-items: start; |
| 819 | +min-height: 58px; |
| 820 | +padding: 10px 12px; |
| 821 | +border: 1px solid var(--border); |
| 822 | +border-radius: var(--radius-md); |
| 823 | +background: var(--card); |
| 824 | +color: var(--text); |
| 825 | +cursor: pointer; |
| 826 | +text-align: left; |
| 827 | +transition: |
| 828 | + border-color var(--duration-fast) ease, |
| 829 | + background var(--duration-fast) ease, |
| 830 | + transform var(--duration-fast) ease; |
| 831 | +} |
| 832 | + |
| 833 | +.settings-text-scale__btn:hover { |
| 834 | +border-color: var(--border-strong); |
| 835 | +background: var(--bg-elevated); |
| 836 | +transform: translateY(-1px); |
| 837 | +} |
| 838 | + |
| 839 | +.settings-text-scale__btn.active { |
| 840 | +border-color: var(--accent); |
| 841 | +background: var(--accent-subtle); |
| 842 | +} |
| 843 | + |
| 844 | +.settings-text-scale__sample { |
| 845 | +font-weight: 650; |
| 846 | +font-size: 13px; |
| 847 | +line-height: 1.2; |
| 848 | +} |
| 849 | + |
| 850 | +.settings-text-scale__label { |
| 851 | +color: var(--muted); |
| 852 | +font-size: 11px; |
| 853 | +line-height: 1.2; |
| 854 | +} |
| 855 | + |
| 856 | +.settings-text-scale__btn.active .settings-text-scale__label { |
| 857 | +color: var(--accent); |
| 858 | +} |
| 859 | + |
804 | 860 | .settings-info-grid { |
805 | 861 | display: grid; |
806 | 862 | gap: 10px; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。