Skip to content

Commit 18b6c4c

Browse files
Ralph Kuepperclaude
andcommitted
fix(windows): layout fixes for sidebar, editor, and button sizing
- Wrap New Connection button in HStack for intrinsic width sizing - Set GravityAreas distribution on connection screen containers - Add DPI-consistent width/height on browser logo - Place editor widget directly in editCard (fills remaining space) - Save/restore edit document state across sessions - Remove reliance on widgetSetHeight inside function bodies (Perry codegen bug workaround) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0fe1816 commit 18b6c4c

1 file changed

Lines changed: 32 additions & 14 deletions

File tree

src/app.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,7 @@ function refreshConnectionList(): void {
498498
if (connectionNames.length === 0) {
499499
// Welcome card with warm styling
500500
const welcomeCard = VStack(16, []);
501+
stackSetDistribution(welcomeCard, -1); // GravityAreas — prevent children from expanding
501502
widgetSetBackgroundColor(welcomeCard, sfR, sfG, sfB, 1.0);
502503
setCornerRadius(welcomeCard, 14);
503504
setPadding(welcomeCard, mobile ? 20 : 32, mobile ? 16 : 36, mobile ? 16 : 28, mobile ? 16 : 36);
@@ -538,11 +539,13 @@ function refreshConnectionList(): void {
538539
widgetSetBackgroundColor(ctaBtn, moR, moG, moB, 1.0);
539540
setCornerRadius(ctaBtn, 8);
540541
setPadding(ctaBtn, 12, 20, 12, 20);
542+
const ctaRow = HStack(0, [ctaBtn, Spacer()]);
543+
widgetSetHugging(ctaRow, 750);
541544

542545
widgetAddChild(welcomeCard, welcomeTitle);
543546
widgetAddChild(welcomeCard, welcomeHint);
544547
widgetAddChild(welcomeCard, pillGrid);
545-
widgetAddChild(welcomeCard, ctaBtn);
548+
widgetAddChild(welcomeCard, ctaRow);
546549

547550
// First-launch analytics notice
548551
if (!getState('analyticsNoticeShown')) {
@@ -557,6 +560,7 @@ function refreshConnectionList(): void {
557560

558561
widgetAddChild(connListContainer, welcomeCard);
559562
widgetMatchParentWidth(welcomeCard);
563+
widgetSetHugging(welcomeCard, 750);
560564
return;
561565
}
562566

@@ -818,6 +822,8 @@ refreshConnectionList();
818822
// --- Hero banner (full-width via ScrollView Width alignment) ---
819823
const heroLogo = ImageFile(mobile ? 'assets/mango-app-icon-40.png' : 'assets/mango-app-icon-44.png');
820824
heroLogo.setSize(mobile ? 40 : 44, mobile ? 40 : 44);
825+
widgetSetWidth(heroLogo, mobile ? 40 : 44);
826+
widgetSetHeight(heroLogo, mobile ? 40 : 44);
821827

822828
const heroTitle = Text('Mango');
823829
textSetFontSize(heroTitle, mobile ? 28 : 38);
@@ -861,6 +867,8 @@ widgetMatchParentWidth(formContainer);
861867

862868
// All content in ScrollView — hero + body
863869
const connContent = VStack(0, [heroBox, connBody]);
870+
stackSetDistribution(connContent, -1); // GravityAreas — children keep intrinsic height inside ScrollView
871+
stackSetDistribution(connBody, -1);
864872

865873
const connectionScreen = ScrollView();
866874
scrollviewSetChild(connectionScreen, connContent);
@@ -869,6 +877,8 @@ widgetSetBackgroundColor(connectionScreen, bgR, bgG, bgB, 1.0);
869877
// Force hero to fill full width
870878
widgetMatchParentWidth(heroBox);
871879
widgetMatchParentWidth(connBody);
880+
widgetSetHugging(heroBox, 750);
881+
widgetSetHugging(connBody, 750);
872882

873883
// ============================================================
874884
// BROWSER SCREEN
@@ -922,6 +932,8 @@ const disconnectBtn = makeDangerBtn(t('Disconnect'), async () => {
922932
// Browser toolbar — logo + connection name + status
923933
const browserLogo = ImageFile('assets/mango-app-icon-24.png');
924934
browserLogo.setSize(24, 24);
935+
widgetSetWidth(browserLogo, 24);
936+
widgetSetHeight(browserLogo, 24);
925937

926938
const browserTitle = Text('Mango');
927939
textSetFontSize(browserTitle, 18);
@@ -1021,12 +1033,9 @@ async function showEditView(docJson: string): Promise<void> {
10211033
ed.setGutterFgColor(tsR, tsG, tsB);
10221034
ed.setCursorColor(moR, moG, moB);
10231035
ed.setSelectionColor(moR, moG, moB, 0.2);
1024-
// Wrap editor in a fixed-height container (embedded NSViews resist height constraints)
1025-
const editorBox = VStack(0, []);
1026-
widgetSetHeight(editorBox, 200);
1027-
widgetAddChild(editorBox, jsonEditor.widget);
1028-
widgetMatchParentWidth(jsonEditor.widget);
1029-
widgetMatchParentHeight(jsonEditor.widget);
1036+
// Editor widget has fills_remaining=true (from embedNSView), so it naturally
1037+
// absorbs remaining space in the editCard VStack with Fill distribution.
1038+
// No wrapper needed — adding directly ensures it's the fill target.
10301039

10311040
const saveBtn = makePrimaryBtn(t('Save Changes'), async () => {
10321041
showStatus(t('Saving...'), false);
@@ -1039,6 +1048,7 @@ async function showEditView(docJson: string): Promise<void> {
10391048
const updateStr = '{"$set":' + compactJson + '}';
10401049
await updateDocument(activeDbName, activeCollName, idFilter, updateStr);
10411050
showStatus(t('Document saved'), false);
1051+
saveState('lastEditDoc', '');
10421052
// Switch back to doc list
10431053
widgetSetHidden(editContainer, 1);
10441054
widgetSetHidden(browserBody, 0);
@@ -1054,13 +1064,15 @@ async function showEditView(docJson: string): Promise<void> {
10541064
} else {
10551065
showStatus(t('Delete failed'), true);
10561066
}
1067+
saveState('lastEditDoc', '');
10571068
widgetSetHidden(editContainer, 1);
10581069
widgetSetHidden(browserBody, 0);
10591070
const result = await queryCollection(activeDbName, activeCollName, lastQueryFilter);
10601071
displayDocs(result);
10611072
});
10621073

10631074
const backBtn = makeGhostBtn(t('Back to results'), () => {
1075+
saveState('lastEditDoc', '');
10641076
widgetSetHidden(editContainer, 1);
10651077
widgetSetHidden(browserBody, 0);
10661078
});
@@ -1070,17 +1082,17 @@ async function showEditView(docJson: string): Promise<void> {
10701082
widgetSetBackgroundColor(editCard, sfR, sfG, sfB, 1.0);
10711083
setCornerRadius(editCard, 12);
10721084
setPadding(editCard, 16, 20, 16, 20);
1085+
const buttonRow = HStack(8, [deleteBtn, Spacer(), backBtn, saveBtn]);
10731086
widgetAddChild(editCard, editHeader);
10741087
widgetAddChild(editCard, Divider());
10751088
widgetAddChild(editCard, fieldLabel);
1076-
widgetAddChild(editCard, editorBox);
1077-
widgetAddChild(editCard, HStack(8, [deleteBtn, Spacer(), backBtn, saveBtn]));
1089+
widgetAddChild(editCard, jsonEditor.widget);
1090+
widgetAddChild(editCard, buttonRow);
10781091

1079-
// editContainer is full-height (HStack .fill), so put card at top + spacer absorbs rest
1092+
// editContainer has Fill distribution — editCard fills remaining space
1093+
// (widgetSetHugging doesn't work inside function bodies due to Perry codegen bug)
10801094
widgetAddChild(editContainer, editCard);
1081-
widgetMatchParentWidth(editCard); // fill the available width so buttons aren't clipped
1082-
widgetSetHugging(editCard, 750); // card stays compact vertically
1083-
widgetAddChild(editContainer, Spacer());
1095+
widgetMatchParentWidth(editCard);
10841096
}
10851097

10861098
// --- Document list ---
@@ -1149,7 +1161,7 @@ function displayDocs(jsonStr: string): void {
11491161
// Header: _id + delete/edit buttons
11501162
const idLabel = makeMonoMuted(idShort, 10);
11511163

1152-
const editBtn = Button('Edit', async () => { await showEditView(docJsonStr); });
1164+
const editBtn = Button('Edit', async () => { saveState('lastEditDoc', docJsonStr); await showEditView(docJsonStr); });
11531165
buttonSetBordered(editBtn, 0);
11541166
buttonSetTextColor(editBtn, moR, moG, moB, 1.0);
11551167

@@ -1683,6 +1695,12 @@ async function restoreLastSession(): Promise<void> {
16831695
textfieldSetString(dbField, lastDb);
16841696
textfieldSetString(collField, lastColl);
16851697
await runQuery(lastDb, lastColl, '{}');
1698+
1699+
// Restore edit view if a document was being edited
1700+
const lastEditDoc = getState('lastEditDoc');
1701+
if (lastEditDoc) {
1702+
await showEditView(lastEditDoc);
1703+
}
16861704
}
16871705
}
16881706
// --- Screenshot mode ---

0 commit comments

Comments
 (0)