improve mobile/touch controls

This commit is contained in:
Brian Beck 2026-03-15 20:49:43 -07:00
parent ae4b7f713b
commit 1af3880280
40 changed files with 171 additions and 78 deletions

View file

@ -65,3 +65,10 @@
height: 0;
}
}
@media (pointer: coarse) {
.Trigger {
padding-top: 12px;
padding-bottom: 12px;
}
}

View file

@ -118,25 +118,10 @@
.Control {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 8px;
}
.Field select {
margin-bottom: 6px;
}
.Field output {
opacity: 0.7;
}
.Tools {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
padding: 10px;
}
.Field {
display: grid;
grid-template-columns: 1fr auto;
@ -149,6 +134,26 @@
margin: 0 0 10px 0;
}
.Field select {
margin-bottom: 6px;
}
.Field input[type="range"] {
max-width: 100px;
}
.Field output {
opacity: 0.7;
}
.Tools {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
padding: 10px;
}
.Field label {
grid-column: 1;
grid-row: 1;
@ -271,3 +276,45 @@
color: #4cb5ff;
cursor: pointer;
}
@media (pointer: coarse) {
.Tools {
padding-top: 12px;
padding-bottom: 13px;
}
.Field {
grid-template-columns: auto minmax(0, 70%);
gap: 0 20px;
margin-bottom: 20px;
}
.Field:has(.Description) {
margin-bottom: 20px;
}
.Field label,
.CheckboxField .Label {
font-size: 14px;
}
.CheckboxField input[type="checkbox"] {
width: 18px;
height: 18px;
padding-right: 6px;
}
.Field select {
width: 100%;
max-width: none;
font-size: 15px;
padding: 4px 6px;
}
.Field input[type="range"] {
width: 100%;
max-width: none;
padding-top: 10px;
padding-bottom: 10px;
}
}

View file

@ -182,17 +182,19 @@ export const InspectorControls = memo(function InspectorControls({
<Accordion value="controls" label="Controls">
<div className={styles.Field}>
<label htmlFor="speedInput">Fly speed</label>
<input
id="speedInput"
type="range"
min={1}
max={100}
step={1}
value={Math.round(speedMultiplier * 100)}
onChange={(event) =>
setSpeedMultiplier(parseFloat(event.target.value) / 100)
}
/>
<div className={styles.Control}>
<input
id="speedInput"
type="range"
min={1}
max={100}
step={1}
value={Math.round(speedMultiplier * 100)}
onChange={(event) =>
setSpeedMultiplier(parseFloat(event.target.value) / 100)
}
/>
</div>
<p className={styles.Description}>
How fast you move in free-flying mode.
{isTouch === false
@ -203,16 +205,18 @@ export const InspectorControls = memo(function InspectorControls({
{isTouch ? (
<div className={styles.Field}>
<label htmlFor="touchModeInput">Joystick</label>{" "}
<select
id="touchModeInput"
value={touchMode}
onChange={(e) =>
setTouchMode(e.target.value as TouchMode)
}
>
<option value="dualStick">Dual stick</option>
<option value="moveLookStick">Single stick</option>
</select>
<div className={styles.Control}>
<select
id="touchModeInput"
value={touchMode}
onChange={(e) =>
setTouchMode(e.target.value as TouchMode)
}
>
<option value="dualStick">Dual stick</option>
<option value="moveLookStick">Single stick</option>
</select>
</div>
<p className={styles.Description}>
Single stick has a unified move + look control. Dual stick
has independent move + look.

View file

@ -145,7 +145,7 @@
}
.Toolbar {
justify-content: center;
justify-content: space-between;
}
.ToggleSidebarButton[data-orientation="left"] {

View file

@ -197,8 +197,36 @@
z-index: 1;
}
.CloseButton {
position: relative;
z-index: 101;
display: grid;
place-content: center;
background: transparent;
padding: 4px 16px 4px 4px;
border: 0;
font-size: 24px;
color: rgba(255, 255, 255, 0.5);
}
.CloseButton[data-open="false"] {
visibility: hidden;
}
@media (max-width: 899px) {
.InputWrapper {
margin-left: 4px;
flex: 1 1 0;
max-width: 460px;
}
.Input {
width: 100%;
}
}
@media (min-width: 900px) {
.CloseButton {
display: none;
}
}

View file

@ -20,6 +20,7 @@ import {
} from "@ariakit/react";
import { matchSorter } from "match-sorter";
import { getMissionInfo, getMissionList, getSourceAndPath } from "../manifest";
import { IoMdCloseCircle } from "react-icons/io";
import orderBy from "lodash.orderby";
import styles from "./MissionSelect.module.css";
@ -335,6 +336,16 @@ export function MissionSelect({
)}
</ComboboxList>
</ComboboxPopover>
<button
type="button"
className={styles.CloseButton}
data-open={isOpen}
onClick={() => {
combobox.setOpen(false);
}}
>
<IoMdCloseCircle />
</button>
</ComboboxProvider>
);
}

View file

@ -38,7 +38,3 @@ body {
padding: 0;
overflow: hidden;
}
input[type="range"] {
max-width: 80px;
}