fix(ui): Fix mobile layout and styling issues
- Add viewport settings to disable user zoom for a better mobile experience - Set fixed height and hide overflow for html, body, and the app container - Use svh units to ensure the shell component displays correctly on mobile devices - Change the chat header layout from flexbox to grid to improve responsive design - Adjust the chat controls area’s grid layout and alignment - Optimize the selector component’s font size and padding for small screens - Hide the divider and adjust the input box’s bottom margin to fit the safe area - Set min-height: 0 to prevent content overflow issues
This commit is contained in:
parent
815d603ce2
commit
e08a640ea0
@ -1,69 +1,18 @@
|
|||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta charset="UTF-8" />
|
||||||
<title>OpenClaw Control</title>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||||
<meta name="color-scheme" content="dark light" />
|
<title>OpenClaw Control</title>
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<meta name="color-scheme" content="dark light" />
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png" />
|
||||||
<script>
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||||
(function () {
|
</head>
|
||||||
var THEMES = { claw: 1, knot: 1, dash: 1 };
|
|
||||||
var MODES = { system: 1, light: 1, dark: 1 };
|
<body>
|
||||||
var LEGACY = {
|
<openclaw-app></openclaw-app>
|
||||||
dark: "claw:dark",
|
<script type="module" src="/src/main.ts"></script>
|
||||||
light: "claw:light",
|
</body>
|
||||||
openknot: "knot:dark",
|
|
||||||
fieldmanual: "dash:dark",
|
|
||||||
clawdash: "dash:light",
|
|
||||||
system: "claw:system",
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
var keys = Object.keys(localStorage);
|
|
||||||
var raw;
|
|
||||||
for (var i = 0; i < keys.length; i++) {
|
|
||||||
if (keys[i].indexOf("openclaw.control.settings.v1") === 0) {
|
|
||||||
raw = localStorage.getItem(keys[i]);
|
|
||||||
if (raw) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!raw) return;
|
|
||||||
var s = JSON.parse(raw);
|
|
||||||
var t = s && s.theme;
|
|
||||||
var m = s && s.themeMode;
|
|
||||||
if (typeof t !== "string") t = "";
|
|
||||||
if (typeof m !== "string") m = "";
|
|
||||||
var legacy = LEGACY[t];
|
|
||||||
var theme = THEMES[t] ? t : legacy ? legacy.split(":")[0] : "claw";
|
|
||||||
var mode = MODES[m] ? m : legacy ? legacy.split(":")[1] : "system";
|
|
||||||
if (mode === "system") {
|
|
||||||
mode = window.matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark";
|
|
||||||
}
|
|
||||||
var resolved =
|
|
||||||
theme === "knot"
|
|
||||||
? mode === "light"
|
|
||||||
? "openknot-light"
|
|
||||||
: "openknot"
|
|
||||||
: theme === "dash"
|
|
||||||
? mode === "light"
|
|
||||||
? "dash-light"
|
|
||||||
: "dash"
|
|
||||||
: mode === "light"
|
|
||||||
? "light"
|
|
||||||
: "dark";
|
|
||||||
document.documentElement.setAttribute("data-theme", resolved);
|
|
||||||
document.documentElement.setAttribute(
|
|
||||||
"data-theme-mode",
|
|
||||||
resolved.indexOf("light") !== -1 ? "light" : "dark",
|
|
||||||
);
|
|
||||||
} catch (e) {}
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<openclaw-app></openclaw-app>
|
|
||||||
<script type="module" src="/src/main.ts"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -4,6 +4,15 @@
|
|||||||
|
|
||||||
/* Tablet and smaller: switch the left nav to a slide-over drawer. */
|
/* Tablet and smaller: switch the left nav to a slide-over drawer. */
|
||||||
@media (max-width: 1100px) {
|
@media (max-width: 1100px) {
|
||||||
|
html[data-ios-mobile]
|
||||||
|
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]):not(
|
||||||
|
[type="submit"]
|
||||||
|
):not([type="reset"]):not([type="file"]):not([type="image"]):not([type="hidden"]),
|
||||||
|
html[data-ios-mobile] textarea,
|
||||||
|
html[data-ios-mobile] select {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.shell,
|
.shell,
|
||||||
.shell--nav-collapsed {
|
.shell--nav-collapsed {
|
||||||
grid-template-columns: minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr);
|
||||||
@ -223,6 +232,55 @@
|
|||||||
|
|
||||||
/* Mobile-specific styles */
|
/* Mobile-specific styles */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
html,
|
||||||
|
body,
|
||||||
|
openclaw-app {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html[data-ios-shell-lock],
|
||||||
|
body[data-ios-shell-lock] {
|
||||||
|
height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
openclaw-app {
|
||||||
|
height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
|
||||||
|
min-height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
|
||||||
|
}
|
||||||
|
|
||||||
|
openclaw-app[data-ios-shell-lock] {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
openclaw-app[data-ios-shell-lock][data-ios-keyboard-open] .content--chat .agent-chat__input {
|
||||||
|
position: fixed;
|
||||||
|
left: 8px;
|
||||||
|
right: 8px;
|
||||||
|
bottom: max(8px, env(safe-area-inset-bottom, 0px));
|
||||||
|
margin: 0;
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
openclaw-app[data-ios-shell-lock][data-ios-keyboard-open] .content--chat .chat-thread {
|
||||||
|
padding-bottom: calc(var(--mobile-chat-input-height, 112px) + 16px);
|
||||||
|
scroll-padding-bottom: calc(var(--mobile-chat-input-height, 112px) + 16px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shell,
|
||||||
|
.shell--chat,
|
||||||
|
.shell--nav-collapsed,
|
||||||
|
.shell--chat-focus {
|
||||||
|
height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
|
||||||
|
min-height: var(--mobile-layout-height, var(--mobile-viewport-height, 100svh));
|
||||||
|
}
|
||||||
|
|
||||||
|
.shell,
|
||||||
|
.shell--nav-collapsed,
|
||||||
|
.shell--chat-focus {
|
||||||
|
grid-template-rows: auto minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
.shell {
|
.shell {
|
||||||
--shell-pad: 8px;
|
--shell-pad: 8px;
|
||||||
--shell-gap: 8px;
|
--shell-gap: 8px;
|
||||||
@ -235,21 +293,43 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topnav-shell {
|
.topnav-shell {
|
||||||
flex-wrap: wrap;
|
flex-wrap: nowrap;
|
||||||
gap: 10px;
|
gap: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topnav-shell__actions {
|
.topnav-shell__actions {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1 1 auto;
|
order: 2;
|
||||||
justify-content: space-between;
|
flex: 1 1 0;
|
||||||
gap: 10px;
|
justify-content: flex-start;
|
||||||
align-items: stretch;
|
gap: 6px;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topnav-shell__content {
|
.topnav-shell__content {
|
||||||
display: none;
|
order: 3;
|
||||||
width: 100%;
|
width: auto;
|
||||||
|
min-width: 0;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topnav-shell .dashboard-header {
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topnav-shell .dashboard-header__breadcrumb {
|
||||||
|
gap: 4px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topnav-shell .dashboard-header__breadcrumb-link {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topnav-shell .dashboard-header__breadcrumb-current {
|
||||||
|
min-width: 0;
|
||||||
|
max-width: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar-nav-toggle {
|
.topbar-nav-toggle {
|
||||||
@ -268,6 +348,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.topbar-status {
|
.topbar-status {
|
||||||
|
flex-shrink: 0;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
width: auto;
|
width: auto;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
@ -275,7 +356,20 @@
|
|||||||
|
|
||||||
.topbar-search {
|
.topbar-search {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
flex: 1;
|
flex: 1 1 0;
|
||||||
|
max-width: none;
|
||||||
|
padding-inline: 10px;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-search__label {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topbar-search__kbd {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topbar-theme-mode {
|
.topbar-theme-mode {
|
||||||
@ -330,76 +424,99 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide the entire content-header on mobile chat — controls are in mobile gear menu */
|
|
||||||
.content--chat .content-header {
|
.content--chat .content-header {
|
||||||
display: none;
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content--chat {
|
.content--chat {
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Show the mobile gear toggle (lives in topbar now) */
|
.content--chat .content-header > div:first-child {
|
||||||
.chat-mobile-controls-wrapper {
|
min-width: 0;
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-mobile-toggle {
|
.content--chat .page-meta {
|
||||||
display: flex;
|
width: auto;
|
||||||
|
justify-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The dropdown panel — anchored below the gear in topbar */
|
.content--chat .chat-controls__session-row {
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown {
|
display: flex;
|
||||||
|
gap: 4px;
|
||||||
|
align-items: center;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .chat-controls__session,
|
||||||
|
.content--chat .chat-controls__model {
|
||||||
|
min-width: 0;
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .chat-controls__session {
|
||||||
|
flex: 2 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .chat-controls__model {
|
||||||
|
flex: 3 1 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .chat-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: end;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
gap: 4px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .chat-controls__session select,
|
||||||
|
.content--chat .chat-controls__model select {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .btn--icon {
|
||||||
|
min-width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
padding: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .btn--icon svg {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content--chat .chat-controls__separator {
|
||||||
display: none;
|
display: none;
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
right: 0;
|
|
||||||
z-index: 100;
|
|
||||||
background: var(--card, #161b22);
|
|
||||||
border: 1px solid var(--border, #30363d);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 8px;
|
|
||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
min-width: 220px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown.open {
|
.content--chat .content-header,
|
||||||
display: flex;
|
.content--chat .chat,
|
||||||
|
.content--chat .chat-split-container,
|
||||||
|
.content--chat .chat-main {
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls {
|
.content--chat .card.chat {
|
||||||
display: flex;
|
padding-top: 0;
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls__session {
|
.content--chat .chat-thread {
|
||||||
min-width: unset;
|
padding-bottom: 8px;
|
||||||
max-width: unset;
|
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls__session select {
|
.content--chat .agent-chat__input {
|
||||||
width: 100%;
|
margin: 0 8px calc(10px + env(safe-area-inset-bottom, 0px));
|
||||||
font-size: 14px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown .chat-controls__thinking {
|
.content--chat .agent-chat__input > textarea {
|
||||||
display: flex;
|
font-size: 16px;
|
||||||
flex-direction: row;
|
|
||||||
gap: 6px;
|
|
||||||
padding: 4px 0;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-mobile-controls-wrapper .chat-controls-dropdown .btn--icon {
|
|
||||||
min-width: 44px;
|
|
||||||
height: 44px;
|
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
padding: 4px 4px 16px;
|
padding: 4px 4px 16px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user