Skip to content

Commit b4fc874

Browse files
NianJiuZstvincentkoc
authored andcommitted
fix(ui): prevent iOS Safari input auto-zoom
1 parent 358b4f2 commit b4fc874

7 files changed

Lines changed: 77 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Docs: https://docs.openclaw.ai
1717
- Channels/Discord: remove Discord-owned queued-run timeout replies through the shared channel lifecycle queue while preserving message ordering and compatibility timeout constants, so long Discord turns stay governed by session/tool/runtime lifecycle instead of channel fallback errors. Thanks @codexGW.
1818
- Agents/tools: clamp `process.poll` waits to 30 seconds, advertise that cap in the tool schema, and honor abort signals while waiting, so long command polls cannot pin agent responsiveness after cancellation. Thanks @vincentkoc.
1919
- Plugin SDK: add tracked Discord component-message helpers and a Telegram account-resolution compatibility facade, so existing plugins using those subpaths resolve while new plugins stay on generic channel SDK contracts. Thanks @vincentkoc.
20+
- Control UI: keep chat, shared form, and config text-entry controls at 16px on touch-primary devices so iOS Safari no longer auto-zooms focused fields. Carries forward #64673. Thanks @NianJiuZst.
2021
- Shared labels: preserve Unicode combining marks and NFC-equivalent accented text in group/channel slug normalization so non-Latin labels no longer lose meaningful characters. Fixes #58932; carries forward #58942 and #58995. Thanks @fengqing-git, @Starhappysh, and @koen666.
2122
- Docs/Hetzner: clarify that SSH tunnel access requires `AllowTcpForwarding local` before running `ssh -L`, so hardened VPS sshd configs do not block loopback Gateway access. Fixes #54557; carries forward #54564; refs #54954. Thanks @satishkc7, @blackstrype, and @Aftabbs.
2223
- Gateway/shutdown: report structured shutdown warnings and HTTP close timeout warnings through `ShutdownResult` while preserving lifecycle hook hardening. Carries forward #41296. Thanks @edenfunf.

ui/src/styles/chat/layout.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,14 @@
565565
box-sizing: border-box;
566566
}
567567

568+
@media (hover: none) and (pointer: coarse) {
569+
.chat-compose .chat-compose__field textarea,
570+
.agent-chat__input > textarea {
571+
/* iOS Safari: inputs < 16px trigger auto-zoom on focus */
572+
font-size: 16px;
573+
}
574+
}
575+
568576
.agent-chat__input > textarea:focus-visible {
569577
box-shadow: none;
570578
}

ui/src/styles/chat/layout.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,15 @@ describe("chat layout styles", () => {
2828
expect(css).toContain("font-size: 20px;");
2929
expect(css).toContain("place-items: center;");
3030
});
31+
32+
it("keeps chat textareas at 16px without misplaced stylelint suppression", () => {
33+
const css = readLayoutCss();
34+
35+
expect(css).toContain("font-size: 14px;");
36+
expect(css).toContain("font-size: 0.92rem;");
37+
expect(css).toMatch(
38+
/@media \(hover: none\) and \(pointer: coarse\) \{[\s\S]*\.chat-compose \.chat-compose__field textarea,[\s\S]*\.agent-chat__input > textarea \{[\s\S]*font-size: 16px;/,
39+
);
40+
expect(css).not.toContain("stylelint-disable-next-line declaration-property-allowed-list");
41+
});
3142
});

ui/src/styles/components.css

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,15 @@
900900
box-shadow: var(--focus-ring);
901901
}
902902

903+
@media (hover: none) and (pointer: coarse) {
904+
.field input,
905+
.field textarea,
906+
.field select {
907+
/* iOS Safari: inputs < 16px trigger auto-zoom on focus */
908+
font-size: 16px;
909+
}
910+
}
911+
903912
.field select {
904913
appearance: none;
905914
padding-right: 36px;

ui/src/styles/components.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,12 @@ describe("agent fallback chip styles", () => {
1414
expect(css).toContain("outline-offset: 2px;");
1515
expect(css).toContain(".agent-chip-input .chip-remove:disabled");
1616
});
17+
18+
it("keeps touch-primary field controls large enough to avoid iOS focus zoom", () => {
19+
const css = readFileSync(path.join(process.cwd(), "ui/src/styles/components.css"), "utf8");
20+
21+
expect(css).toMatch(
22+
/@media \(hover: none\) and \(pointer: coarse\) \{[\s\S]*\.field input,[\s\S]*\.field textarea,[\s\S]*\.field select \{[\s\S]*font-size: 16px;/,
23+
);
24+
});
1725
});

ui/src/styles/config.css

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,21 @@
13161316
border-color: var(--border);
13171317
}
13181318

1319+
@media (hover: none) and (pointer: coarse) {
1320+
.config-search__input,
1321+
.settings-theme-import__input,
1322+
.config-raw-field textarea,
1323+
.cfg-input,
1324+
.cfg-input--sm,
1325+
.cfg-textarea,
1326+
.cfg-textarea--sm,
1327+
.cfg-number__input,
1328+
.cfg-select {
1329+
/* iOS Safari: inputs < 16px trigger auto-zoom on focus */
1330+
font-size: 16px;
1331+
}
1332+
}
1333+
13191334
/* Segmented Control */
13201335
.cfg-segmented {
13211336
display: inline-flex;

ui/src/styles/config.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { readFileSync } from "node:fs";
2+
import path from "node:path";
3+
import { describe, expect, it } from "vitest";
4+
5+
describe("config styles", () => {
6+
it("keeps touch-primary config text controls large enough to avoid iOS focus zoom", () => {
7+
const css = readFileSync(path.join(process.cwd(), "ui/src/styles/config.css"), "utf8");
8+
9+
expect(css).toContain("@media (hover: none) and (pointer: coarse)");
10+
for (const selector of [
11+
".config-search__input",
12+
".settings-theme-import__input",
13+
".config-raw-field textarea",
14+
".cfg-input",
15+
".cfg-input--sm",
16+
".cfg-textarea",
17+
".cfg-textarea--sm",
18+
".cfg-number__input",
19+
".cfg-select",
20+
]) {
21+
expect(css).toContain(selector);
22+
}
23+
expect(css).toContain("font-size: 16px;");
24+
});
25+
});

0 commit comments

Comments
 (0)