fix: compact map geometry controls

This commit is contained in:
Nico 2026-06-04 00:34:18 -07:00
parent 2b534eed6a
commit 164a95e058
3 changed files with 127 additions and 54 deletions

View File

@ -300,56 +300,70 @@ export default function LocationMapBottomSheet({
Locked
</label>
</div>
<div className="location-map-object-grid">
<div className="location-map-geometry-controls">
<div className="location-map-geometry-group">
<span className="location-map-geometry-title">Position</span>
<div className="location-map-geometry-row">
<label>
X
<span>X</span>
<input
type="number"
min="0"
max={maxX}
step="1"
value={Math.round(selectedObject.x)}
aria-label="X position"
disabled={saving || geometryLocked}
onChange={(event) => onObjectField("x", Number(event.target.value))}
/>
</label>
<label>
Y
<span>Y</span>
<input
type="number"
min="0"
max={maxY}
step="1"
value={Math.round(selectedObject.y)}
aria-label="Y position"
disabled={saving || geometryLocked}
onChange={(event) => onObjectField("y", Number(event.target.value))}
/>
</label>
</div>
</div>
<div className="location-map-geometry-group">
<span className="location-map-geometry-title">Size</span>
<div className="location-map-geometry-row">
<label>
W
<span>W</span>
<input
type="number"
min="40"
max={maxWidth}
step="1"
value={Math.round(selectedObject.width)}
aria-label="Width"
disabled={saving || geometryLocked}
onChange={(event) => onObjectField("width", Number(event.target.value))}
/>
</label>
<label>
H
<span>H</span>
<input
type="number"
min="40"
max={maxHeight}
step="1"
value={Math.round(selectedObject.height)}
aria-label="Height"
disabled={saving || geometryLocked}
onChange={(event) => onObjectField("height", Number(event.target.value))}
/>
</label>
</div>
</div>
</div>
{geometryLocked ? (
<p className="location-map-muted location-map-lock-note">
Unlock this area before moving or resizing it.

View File

@ -610,10 +610,55 @@
padding: 0;
}
.location-map-object-grid {
.location-map-geometry-controls {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 0.45rem;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.5rem;
}
.location-map-geometry-group {
display: grid;
gap: 0.35rem;
min-width: 0;
}
.location-map-geometry-title {
color: #cbd5e1;
font-size: 0.78rem;
font-weight: 900;
}
.location-map-geometry-row {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0.35rem;
}
.location-map-geometry-row label {
min-width: 0;
display: flex;
align-items: center;
gap: 0.35rem;
padding: 0.3rem 0.45rem;
border: 1px solid var(--color-border-light);
border-radius: 8px;
background: rgba(15, 23, 34, 0.58);
color: #f8fafc;
}
.location-map-geometry-row label span {
flex: 0 0 auto;
min-width: 1.1rem;
color: #9fb3c8;
font-size: 0.76rem;
font-weight: 900;
}
.location-map-geometry-row input {
min-width: 0;
min-height: 34px;
padding: 0.35rem 0.4rem;
text-align: center;
}
.location-map-lock-note {
@ -843,7 +888,7 @@
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.location-map-object-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
.location-map-geometry-controls {
gap: 0.45rem;
}
}

View File

@ -2028,6 +2028,14 @@ test("mobile editor uses bottom sheet controls instead of desktop object toolbar
const labelInput = page.getByRole("textbox", { name: "Label" });
await expect(labelInput).toBeVisible();
await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Bakery");
const geometryControls = page.locator(".location-map-geometry-controls");
await expect(geometryControls).toBeVisible();
await expect(geometryControls.getByText("Position")).toBeVisible();
await expect(geometryControls.getByText("Size")).toBeVisible();
await expect(page.getByLabel("X position")).toHaveValue("40");
await expect(page.getByLabel("Y position")).toHaveValue("40");
await expect(page.getByLabel("Width")).toHaveValue("260");
await expect(page.getByLabel("Height")).toHaveValue("160");
const selectedPrimaryActions = page.locator(".location-map-selected-primary-actions");
const selectedSecondaryActions = page.locator(".location-map-selected-secondary-actions");
await expect(selectedPrimaryActions.getByRole("button", { name: "Save Draft" })).toBeVisible();
@ -2042,6 +2050,12 @@ test("mobile editor uses bottom sheet controls instead of desktop object toolbar
throw new Error("Selected object draft actions were not measurable");
}
expect(selectedPrimaryBox.y).toBeLessThan(labelBox.y);
const geometryBox = await geometryControls.boundingBox();
expect(geometryBox).not.toBeNull();
if (!geometryBox) {
throw new Error("Geometry controls were not measurable");
}
expect(geometryBox.height).toBeLessThanOrEqual(92);
await page.getByRole("button", { name: "Done" }).click();
await expect(page.getByRole("textbox", { name: "Label" })).toHaveCount(0);
await expect(page.locator(".location-map-sheet-header strong")).toHaveText("Edit Objects");