feat(ui): UE polish — graded toasts, button loading, copy feedback, keyboard (v1.16) - #40
Merged
Merged
Conversation
…eyboard (v1.16) rant 2026-08-17T15:50:05 (UI polish & UE, section B interaction): - toast grading: toast(msg, type) with success/error/info styles; all 39 call sites classified (validation errors, success confirmations, info) - button loading state: withLoading(btn, fn) spinner + disable for topup / raise / dept confirm and share-form submit - copy feedback: API Key copy button flashes copied state for 1.2s (fallback path shows Ctrl+C hint) - keyboard accessibility: Enter submits topup/raise/dept inline forms; Esc closes topup/raise/dept cards; focus managed on open - docs: user-stories v1.16, ui/README interaction conventions
7 tasks
argszero
added a commit
that referenced
this pull request
Sep 22, 2026
…es (#290) The forgot-password success branch called toast(T("forgot.done"), "ok"); reusing the API response's own status literal (`if (r.status === "ok")`, same branch) as a toast *level*. `toast()` concatenates `type` into the element's class with no validation: el.className = "toast" + (type ? " " + type : ""); // ui/js/app.js:38 and `ui/css/style.css` declares `.toast.success` / `.toast.error` / `.toast.info` only — `.toast.ok` exists solely in the design prototype (`docs/prototype/aitokenpool-console.html`, whose own calls use `ok`/`warn`). So the app's only password-reset success message silently fell back to the base `.toast` style. `#40` introduced the product vocabulary and migrated the call sites; `8ac018b` (forgot/reset password, three days later) wrote one new call site back in the prototype's words. Fix: use `"success"`, the word the running app already uses for a genuine success on the same auth card, and say why the argument is a level. The new static gate `state_gate::every_toast_level_is_a_level_the_sheet_declares` pins the shape with three derived rules (no hand-written rosters): 1. every literal level at a `toast(...)` call site is in the sheet's `.toast.<x>` rule set minus the state classes the function body applies itself via `classList.add`; 2. that vocabulary equals, both ways, the contract line in `ui/README.md`; 3. conversely, every graded rule has a call site (no dead level). `the_r92_rules_have_teeth` and `the_r92_rules_separate_the_variants` prove each rule has its own tooth and declare each leg's verdict; the competitive fix ("leave the call site, add a `.toast.ok` rule") is rejected by rule 2, and the jsdom probe rejects it too.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Interaction (UE) polish (rant
2026-08-17T15:50:05, section B) — final PR of the UI/UE polish wave:toast(msg, type)— success / error / info styles (border + text color); all 39 call sites classified (validation failures → error, confirmations → success, informational → info).withLoading(btn, fn)helper (spinner + disable, restores after simulated feedback) applied to 充值 / 申请加额 / 部门确认 / 上架提交 buttons.Acceptance criteria for rant 15:50:05 now all satisfied: modal→inline (PR #38), visual polish (PR #39), and interaction polish (this PR) — wave complete.
Self-verified:
node --check+ DOM smoke test (init path runs clean) + all$("#id")refs ↔ HTML ids cross-checked +cargo testpasses.Related Issue
(no issue — host rant driven:
2026-08-17T15:50:05)Changes
Tests
cargo test全部通过(1 passed)cargo fmt --check通过(无 Rust 改动)Checklist