fix(folio): scope all ax selectors through screen root nodes

Use desc:ScreenName > desc:element path queries so every selector is
rooted at the screen level. focusedInput stays unscoped since it lives
in the app root, outside any screen.
This commit is contained in:
pj committed 2026-04-25 19:50:26 +07:00
1 parent cd11faf1fa
commit 0708655ec1
1 file changed
+24 -21
+24 -21
View File
@@ -36,38 +36,41 @@ function parseCents(desc: string | null | undefined): number {
return Number(parts[1]) || 0; return Number(parts[1]) || 0;
} }
// Screen detection via unique element presence // Route and auth state derived from screen root nodes
const loggedIn = extract(s => s.ax.find("desc:login_submit") == null); const loggedIn = extract(s => s.ax.find("desc:LoginScreen") == null);
const route = extract<string | null>(s => { const route = extract<string | null>(s => {
if (s.ax.find("desc:login_submit")) return "login"; if (s.ax.find("desc:LoginScreen")) return "login";
if (s.ax.find("desc:add_account_button")) return "home"; if (s.ax.find("desc:HomeScreen")) return "home";
if (s.ax.find("desc:account_name_field")) return "add-account"; if (s.ax.find("desc:AddAccountScreen")) return "add-account";
if (s.ax.find("descPrefix:active_account:")) return "ledger"; if (s.ax.find("desc:LedgerScreen")) return "ledger";
if (s.ax.find("desc:txn_amount")) return "add-transaction"; if (s.ax.find("desc:AddTransactionScreen")) return "add-transaction";
return null; return null;
}); });
const accounts = extract(s => s.ax.findAll("descPrefix:account:") // All element lookups scoped through their screen root
const accounts = extract(s => s.ax.findAll("desc:HomeScreen > descPrefix:account:")
.map(el => parseAccount(el.desc))); .map(el => parseAccount(el.desc)));
const ledgerRows = extract(s => s.ax.findAll("descPrefix:ledger_row:") const ledgerRows = extract(s => s.ax.findAll("desc:LedgerScreen > descPrefix:ledger_row:")
.map(el => parseLedgerRow(el.desc))); .map(el => parseLedgerRow(el.desc)));
const ledgerBalance = extract(s => const ledgerBalance = extract(s =>
parseCents(s.ax.find("descPrefix:ledger_balance:")?.desc)); parseCents(s.ax.find("desc:LedgerScreen > descPrefix:ledger_balance:")?.desc));
const activeAccountId = extract(s => const activeAccountId = extract(s =>
s.ax.find("descPrefix:active_account:")?.desc?.split(":")[1] ?? null); s.ax.find("desc:LedgerScreen > descPrefix:active_account:")?.desc?.split(":")[1] ?? null);
// focusedInput lives in the app root (not inside any screen), so unscoped
const focusedInput = extract(s => const focusedInput = extract(s =>
s.ax.find("descPrefix:focused_input:")?.desc?.split(":")[1] ?? null); s.ax.find("descPrefix:focused_input:")?.desc?.split(":")[1] ?? null);
const loginEmailField = extract(s => s.ax.find("desc:login_email")); const loginEmailField = extract(s => s.ax.find("desc:LoginScreen > desc:login_email"));
const loginPasswordField = extract(s => s.ax.find("desc:login_password")); const loginPasswordField = extract(s => s.ax.find("desc:LoginScreen > desc:login_password"));
const loginSubmit = extract(s => s.ax.find("desc:login_submit")); const loginSubmit = extract(s => s.ax.find("desc:LoginScreen > desc:login_submit"));
const addAccountButton = extract(s => s.ax.find("desc:add_account_button")); const addAccountButton = extract(s => s.ax.find("desc:HomeScreen > desc:add_account_button"));
const accountNameField = extract(s => s.ax.find("desc:account_name_field")); const accountNameField = extract(s => s.ax.find("desc:AddAccountScreen > desc:account_name_field"));
const addAccountSubmit = extract(s => s.ax.find("desc:add_account_submit")); const addAccountSubmit = extract(s => s.ax.find("desc:AddAccountScreen > desc:add_account_submit"));
const addTxnButton = extract(s => s.ax.find("desc:add_txn_button")); const addTxnButton = extract(s => s.ax.find("desc:LedgerScreen > desc:add_txn_button"));
const txnAmountField = extract(s => s.ax.find("desc:txn_amount")); const txnAmountField = extract(s => s.ax.find("desc:AddTransactionScreen > desc:txn_amount"));
const txnSubmit = extract(s => s.ax.find("desc:txn_submit")); const txnSubmit = extract(s => s.ax.find("desc:AddTransactionScreen > desc:txn_submit"));
const accountCards = extract(s => s.ax.findAll("descPrefix:account:")); const accountCards = extract(s => s.ax.findAll("desc:HomeScreen > descPrefix:account:"));
const backButton = extract(s => s.ax.find("desc:Back")); const backButton = extract(s => s.ax.find("desc:Back"));
// Property 1: every new account starts with balance === 0 // Property 1: every new account starts with balance === 0