import SwiftUI // Draft observation stays in these small views, away from the grid hierarchy. struct SheetFormulaBar: View { @Bindable var model: SheetModel var formulaFocused: FocusState.Binding var body: some View { HStack { TextField("Cell or range", text: $model.rangeText).frame(width: 110).onSubmit { model.selectRange() }.accessibilityLabel("Cell or range, for example A1:B5") Text("fx").foregroundStyle(.secondary) TextField("Cell contents or formula", text: $model.draft).focused(formulaFocused).disabled( !model.mayWrite || model.busy || !model.failedWrites.isEmpty ) .autocorrectionDisabled() #if os(iOS) .textInputAutocapitalization(.never) #endif .onSubmit { Task { await model.commit() } } .onKeyPress(.escape) { model.discard() return .handled } .onKeyPress(.tab) { Task { await model.commit(moveRight: true) } return .handled } if model.dirty { Button(sheetsMacString("Save")) { Task { await model.commit() } }.disabled(model.busy) Button("Discard") { model.discard() }.disabled(model.busy) } }.textFieldStyle(.roundedBorder).padding(8) } } struct SheetStatusBar: View { var model: SheetModel var body: some View { HStack { Text(model.page?.Sheet.TabName ?? "Sheet") Spacer() if model.busy { ProgressView().controlSize(.small) } Text(model.dirty ? "Unsaved cell edit" : model.notice) Text(model.live).foregroundStyle(.secondary) }.font(.caption).padding(8) } }