Skip to content

feat: centralise button loading spinner - #1

Open
abbaskachia wants to merge 503 commits into
abbaskachia:mainfrom
Remitwise-Org:main
Open

feat: centralise button loading spinner#1
abbaskachia wants to merge 503 commits into
abbaskachia:mainfrom
Remitwise-Org:main

Conversation

@abbaskachia

Copy link
Copy Markdown
Owner

Closes Remitwise-Org#919

Replaces custom inline spinners at 7 call-sites with a shared Button
component that handles aria-busy, disabled, and the Loader2 spinner
in one place.

Changes

  • components/ui/Button.tsx (new) — forwardRef wrapper; adds loading
    prop; sets aria-busy="true" and disabled when loading; renders spinner
    with aria-hidden and motion-reduce:hidden
  • Migrated: ReviewStep, EmergencyTransferModal, PolicyDetail (×2),
    NewPolicyForm, SessionExpiryNotification, SettingsPrimitives.SaveButton,
    bills/page
  • docs/COMPONENTS.md — Button entry added

Testing

  • Existing tests pass: send-flow-cta, SettingsPrimitives, modal-inert-behavior
  • No new behaviour introduced — purely a structural consolidation

Baskarayelu and others added 30 commits July 27, 2026 10:51
Adds docs/RTL_TESTING.md covering three methods for verifying
components in a right-to-left (Arabic/Hebrew) locale:

- Method A: Vitest unit tests using RtlWrapper from
  components/i18n/rtlDecorator.tsx with concrete FormattedCurrency
  examples
- Method B: Storybook visual verification using rtlDecorator factory,
  including what to inspect and how to run locally
- Method C: Playwright E2E using addInitScript injection, matching the
  pattern in tests/e2e/rtl-layout.spec.ts

Also includes authoring guidance (Tailwind rtl: variants, logical
properties, no hard-coded directional CSS), a code-review checklist,
and cross-links to related docs.

Links the new guide from README.md after the Responsive Testing Guide
reference in the End-to-End Testing section.

Closes #
- Add ApprovalRequestCard component: requester identity, action/amount,
  approver avatar strip (filled/empty slots), progress text, approve/reject
  buttons; status always conveyed by icon + text (WCAG 2.1 AA)
- Extend ApprovalStatus with requested, partially_approved, rejected
- Add requester and amount fields to ApprovalItem
- Add rejectItem() to useApprovalsQueue hook
- ADD_SIGNATURE now produces partially_approved when below threshold
- ApprovalsQueue: pending section uses ApprovalRequestCard; history section
  shows terminal items (approved/rejected/expired) as compact HistoryRow;
  empty state shown when no pending approvals
- Add docs/family-multisig-approval-ux.md: state machine, component
  anatomy, status token table, role definitions, a11y notes
… list, and UX spec (admin merge, -X theirs)
Replace the placeholder with a 4-step wizard: recipient → amount → review → confirm.

Changes:
- Add typed ReceiptData interface, remove 'any' from transactionData
- Fix splits property (dailySpending → spending) to match TransactionSuccessReceiptProps
- Add aria-current='step' and progress indicator with completed checkmarks
- Add aria-live polite region for screen-reader step announcements
- Add stepHeadingRef + useEffect for keyboard focus management on step change
- Label all interactive elements: htmlFor on inputs, aria-label on buttons
- Wrap speed toggles in <fieldset> with sr-only legend
- Apply brand-red glow only on the final confirm card (purposeful, not noise)
- Refine microcopy: 'Good to know before you send' and 'Please double-check'
  replace alarmist headers while preserving irreversibility facts
- Document relationship to Dashboard/EmergencyTransferModal and
  send/components/EmergencyTransferModal via JSDoc
- Add focus-visible rings on all interactive elements
Adds useSaveData hook and applies it across all five chart widgets.
When navigator.connection.saveData is true, each chart renders a
lightweight static alternative instead of the Recharts visualisation,
avoiding SVG rendering, animation timers, and heavy bundle code on
metered connections.

Changes:
- lib/hooks/useSaveData.ts — new SSR-safe, reactive hook (mirrors
  usePrefersReducedMotion pattern; graceful degradation on browsers
  without Network Information API support)
- SixMonthTrendsWidget — plain <table> of monthly figures
- MoneyDistributionWidget — <ul> bar list with CSS progress bars
- RemittanceTrendChart — ordered list of date / amount pairs
- CategoryDonutChart — static progress bars (no interactive donut)
- SpendingVsSavingsChart — plain <table> with spending and savings cols
- tests/unit/hooks/useSaveData.test.ts — 6 unit tests covering default,
  initial value, reactivity, listener cleanup, and missing addEventListener
- docs/HOOKS.md — useSaveData entry with usage, table of consumers,
  and Chromium DevTools testing instructions

Closes #
…fallbacks

feat: honour Save-Data header with lower-fi chart fallbacks
- Replace static placeholder grid with live data via useStaleFetch

- StatCard descriptor variant (detail2) for counts: transfers, paid, policies

- Locale-aware currency formatting via navigator.language

- Loading skeleton, error fallback with retry, dismissable stale-data banner

- Responsive grid: grid-cols-1 sm:grid-cols-2 lg:grid-cols-4
- Define button variant/state matrix with 4 variants (primary, secondary, destructive, ghost)
- Standardize focus rings using ring-focus/ring-offset-focus tokens
- Replace inconsistent colors (bg-red-600, gradients) with brand tokens
- Update 15 buttons across insurance, family, emergency-transfer pages
- Eliminate stray blue button in ShortcutTooltip stories
- Add active states and proper disabled semantics
- Document button system, migration log, and testing checklist

Closes #1323
…tons

- Design disabled-to-active New Policy creation flow with coverage type, premium, and coverage amount inputs
- Replace bg-blue-600/bg-blue-700 with brand.red/brand.redHover tokens
- Specify disabled pre-integration button state with descriptive microcopy
- Redline PolicyCard and Total Monthly Premium summary relationship
- Document active vs disabled button states and transitions
- Ensure a11y compliance with button labels, disabled semantics, and contrast ratios
- Visual QA at 375px and 1280px breakpoints

Closes #1302
Add docs/SEMANTIC_TOKENS_AND_CONTRAST.md — a contributor-focused guide covering:
- What semantic tokens are and the four token families (brand, status, primary, spacing)
- The two-layer token architecture (CSS custom properties + Tailwind theme extensions)
- WCAG 2.1 AA contrast ratio requirements with thresholds for normal and large text
- Three verification methods: Vitest tests, Python script, programmatic helpers
- Step-by-step process for adding new colour tokens with contrast verification
- Common pitfalls (colour-only states, hard-coded focus rings, opaque equivalents)
- PR checklist for token changes

Link the new doc from README.md (Design Notes section) and docs/THEMING.md (Contributor Checklist).

Closes #SEMANTIC_TOKENS
- Add comprehensive docs/SCREEN_READER_SUPPORT.md covering supported screen readers, testing procedures, and keyboard-only walkthrough guidance
- Fix FAQSection: add aria-controls, role=region, aria-labelledby, hidden attribute for collapsed panels, and aria-hidden on decorative icons
- Fix Hero: add aria-hidden to decorative trust-indicator SVGs
- Fix WhyChooseStellar: add aria-hidden to decorative icon containers
- Fix QuickActions: improve semantic structure with nav, ul/li elements, and aria-label
- Fix NavLinks: add aria-label to nav element
- Fix settings/page.tsx: add missing useEffect and useRef imports
- Add tests/e2e/landing-a11y.spec.ts: Playwright axe scan and keyboard tests for landing page

Closes #SCREEN_READER_SUPPORT
- preview.yml: replace invalid actions/setup-node commit SHA with v4 tag
- preview.yml: replace actions/checkout commit SHA with v4 for consistency
- storybook-tests.yml: use local .bin/http-server instead of npx to avoid resolution failures
- Registers keydown listener, fires on match, unregisters on unmount
- Handles platform mod keys (metaKey/macOS + ctrlKey/Windows)
- Supports shift and alt modifiers
- ignoreWhenEditing option suppresses shortcuts while typing
- 33 tests covering registration, matching, non-matching, unregistration,
  platform mod keys, ignoreWhenEditing, preventDefault, and handler staleness
Baskarayelu and others added 30 commits July 30, 2026 11:05
ci: add axe-core WCAG 2.1 A/AA scan across every top-level route
…rch-query

Harden: sanitize the search query before it hits the URL
ci: run lint and typecheck as parallel jobs (Closes #1501)
Validate: reject invalid IBAN before submit
…enumber

Validate: reject phone numbers that fail libphonenumber
Perf: swap the moment.js usage for date-fns
…ated-client

API: swap the ad-hoc fetch for the generated client on /transactions
DX: add a `just seed-invoice` helper for local testing
DX: one-command mock backend for local dev
…ction-list

Perf: virtualize the transaction list over 200 rows
DX: add a `dev:reset` script that clears local storage
Adds wipeClientState() that defensively sweeps auth keys, form-prefixed
localStorage entries, and known sessionStorage draft keys on logout.
- Exports AUTH_STORAGE_KEYS, FORM_STATE_PREFIX, SESSION_STORAGE_FORM_KEYS
- Updates clearAuthState to call wipeClientState
- Updates tests to verify the wipe chain
…ate-logout

fix: harden wipe form state on logout
…earch, and paste

- docs/CSRF_PROTECTION.md: document SameSite=Lax first-party defence,
  nonce-based wallet auth, open-redirect guard, form-state wipe on
  logout, search-query sanitization, and clipboard paste stripping
  (Closes #1163)

- Redirect hardening: safeRedirectPath() in lib/client/logout.ts and
  useCredentialRevoke.ts already rejects absolute and protocol-relative
  URLs; tests in tests/unit/logout-client.test.ts confirm both the
  happy path and rejection cases (Closes #1431)

- Form state wipe on logout: wipeClientState() in sessionHandler.ts
  clears all known auth keys, remitwise_form_* localStorage entries,
  and sessionStorage draft keys on every clearAuthState() call; add
  dedicated tests in tests/unit/sessionHandler.test.ts (Closes #1430)

- Search query sanitization: apply sanitizeSearchQuery() from
  lib/sanitize.ts in app/search/page.tsx (reads ?q= param) and
  components/CommandPalette.tsx (builds /search?q= URL); add
  negative tests for control-char injection and overlong input
  (Closes #1419)

- Clipboard paste rejection: add onPaste handler to
  TransactionHistorySearchInput that strips HTML tags via
  sanitizePastedValue() when the clipboard carries a text/html MIME
  type; add tests for the HTML-stripping path and the plain-text
  no-op path (Closes #1401)
- Add missing useSafeReload import to WalletSection
- Wire SaveButton onSave guard to block save when IBAN is invalid
- Add all missing settings.wallet.* i18n keys (en + es)
…ubmit

Closes #1418: Implemented: validate: reject invalid IBAN before submit  #1418
…ening

security: CSRF protection docs and client-side hardening baseline
…_fetches_on_the_dashboard

Perf: collapse two identical fetches on the dashboard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a loading prop on the Button component