Repository navigation
WEBDEV-9053: Migrate the donation form payment layer into elements - #103
Merged
Merged
Conversation
… form section into elements Bottom rung of the donation form stack. The data-models, currency-validator and form-section packages from iaux-donation-form land in src/elements/ia-donation-form/ as models/, currency-validator.ts and form-elements/ia-donation-section.ts. The 14 model files fold into six. The enums become as-const objects plus a type, since erasableSyntaxOnly rules out enum. The classes stay classes: offshoot, the monthly giving portal and the petabox banner all construct them. The section is ia-donation-section, sized off a 10px base font size variable like the item navigator so it renders the same under any root font size, with its CSS variables renamed to --ia-donation-section-*. story-template gets an importPath property so an element nested inside another component's directory shows the right import snippet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QnX6VHo3EJRzcKfhzBChCf
The edit-donation package from iaux-donation-form lands as ia-donation-edit-donation under src/elements/ia-donation-form/form-elements/, rendering ia-donation-section for its two steps. The petabox banner uses it on its own, so it gets its own story. Enums become as-const objects plus a type. CSS variables move to --ia-donation-edit-*, sized off a 10px base font size that is passed through to the sections. The strings go through msg(), the custom amount field gets an accessible name, and currency.js becomes a dependency. One inherited bug fixed: with the custom amount hidden, the "is the donor typing in the custom field" check compared null to null and came out true, so a preset set programmatically could end up with nothing selected. Guarded on the field existing, with a test. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QnX6VHo3EJRzcKfhzBChCf
The Braintree manager, payment clients and the five provider handlers (credit card, PayPal, Venmo, Apple Pay, Google Pay) land under src/elements/ia-donation-form/braintree/, with the recaptcha manager, the Venmo session restoration handler and DonationFormError alongside. No custom elements in this rung. The flow handlers go with the modals next. The vendored 2020 braintree-web and paypal-checkout-components d.ts files are replaced by the real @types packages, which split the library module (typeof braintree.client) from the instance (braintree.Client), so the clients and handlers are typed that way. The fee_amount_covered custom field is calculated from the fields like the total already was, since donationInfo can arrive as a plain object. The hosted fields retry no longer uses an async promise executor and clears its timer whichever way the race goes. The recaptcha onload callback global is namespaced so it can't collide with the old package's on a page that loads both. Tests move from web-test-runner and sinon to Vitest, with the payment library mocks under test-helpers/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QnX6VHo3EJRzcKfhzBChCf
jbuckner
added this pull request to stack #101
September 15, 2026 05:05
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #103 +/- ##
==========================================
+ Coverage 90.67% 90.96% +0.28%
==========================================
Files 96 118 +22
Lines 3519 4107 +588
Branches 843 904 +61
==========================================
+ Hits 3191 3736 +545
- Misses 137 170 +33
- Partials 191 201 +10 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…onation-form-models * origin/main: 1.1.1 (#118) WEBDEV-9132: Fix Safari image-viewer wide-layout breakpoint (#115) 1.1.0 (#116) WEBDEV-9129: Exclude story files from coverage reporting (#113) WEBDEV-9121: Migrate histogram-date-range into elements (#112) WEBDEV-9130: Exclude nested dist and worktree tests from local runs (#114) v1.0.0 (#111) WEBDEV-9025: Add a CLAUDE.md covering the publish flow (#94) WEBDEV-9063: Typecheck in CI (#107) v0.4.1 (#108) WEBDEV-9066: Guard custom element registration against duplicate defines (#106) v0.4.0 (#99) WEBDEV-9022: Migrate the image viewer into elements (#93)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013RS8ThjiMNiq7HBBAGash1
…onation-form-models Main removed src/elements/index.ts (WEBDEV-9214), so the donation form re-exports this branch added to it go with it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ
…te-edit-donation Keeps both currency.js and dayjs in package.json. Main removed src/elements/index.ts (WEBDEV-9214), so the edit-donation re-export goes with it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ
The lint rule that came in from main restricts customElement from lit/decorators.js. Same change #98 made for the section. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ
Ports iaux-donation-form#188 (WEBDEV-8781). Safari private browsing throws a SecurityError from reading the localStorage or sessionStorage global, so the lookup now happens inside the guarded probe. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ
Ports the payment layer part of iaux-donation-form#190. The credit card form focuses the card number field when the donor picks credit card. The vendored braintree hosted-fields type patch isn't needed here since @types/braintree-web already declares HostedFields.focus. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ
…ent-layer Main removed src/elements/index.ts (WEBDEV-9214), so the payment layer re-exports go with it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ
…dit-donation Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ * origin/main: WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98) # Conflicts: # src/elements/ia-donation-form/element-names.test.ts
…ent-layer Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S8FoDPcJXekJd1rL9b9oJJ * WEBDEV-9052-migrate-edit-donation: WEBDEV-9051: Migrate the donation form models, currency validator and form section into elements (#98)
latonv
approved these changes
Oct 8, 2026
latonv
left a comment
Member
There was a problem hiding this comment.
LGTM, solid migration! Just flagged one oddity in the dependencies.
Use the stable promised-singleton 0.2.1. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012rHVriHUtoMwtEUwFdyZdS
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.
WEBDEV-9053. Stacked on #100. Fourth of the five in WEBDEV-8602.
The payment layer of
donation-form: the Braintree manager, payment clients, the five provider handlers (credit card, PayPal, Venmo, Apple Pay, Google Pay), the recaptcha manager and the Venmo session restoration handler. It lands undersrc/elements/ia-donation-form/braintree/. No custom elements in this one, so no story, it's the logic and its tests. The flow handlers go with the modals in the last rung since they render them.What changed beyond the move:
@typesinstead of the vendored 2020 copies.@types/braintree-web3.143 splits the library module (typeof braintree.client, the thing withcreate()) from the instance (braintree.Client), where the old copy conflated them.PaymentClientsInterfaceand the handlers are typed that way now, and everything imports the types (import type * as braintree from 'braintree-web') rather than leaning on the UMD global. Aglobals.d.tstypeswindow.braintreeandwindow.paypal, which the CDN scripts create. The@typespackages are regular dependencies because the published d.ts files reference them.fee_amount_coveredis calculated from the fields.submitDonationalready recomputed the total becausedonationInfocan arrive as a plain object (Venmo in Chrome) with none of the class getters. The fee custom field read thefeeAmountCoveredgetter and would have beenundefinedin that case. Both are calculated the same way now, with a test using a plain object.finallyso a lost race can't leave a rejection with nowhere to go. Same behavior: our own timer races Braintree's create, a timer win retries, up to the max.iaDonationFormGrecaptchaLoaded). The old package usesdonationFormGrecaptchaLoadedCallback, and a page loading both during the switch-over would have had them overwrite each other's callback and hang one form's recaptcha.HostedFieldContainerdoesn't importBadgedInput. It only ever set.erroron the parent, so it types the parent as an element with anerrorflag. The badged input element itself arrives with the form elements.as constobjects plus a type, as in the earlier rungs.CreditCardHandlerhas afocusFieldthe form uses to focus the card number (from iaux-donation-form#190).@types/braintree-webalready hasHostedFields.focus, so the vendored type patch isn't needed.Tests moved from web-test-runner and sinon to Vitest, 88 of them. The mocks for the payment libraries live in
braintree/test-helpers/*.test-helpers.ts, which the package's!dist/**/*.test*filter keeps out of the published tarball. The Apple Pay session mock now definesSTATUS_SUCCESSandSTATUS_FAILURE, which the old one didn't, so those assertions comparedundefinedtoundefinedand passed regardless.Verified locally: build, full suite 1117 passing, eslint and prettier clean, no circular dependencies.
🤖 Generated with Claude Code
https://claude.ai/code/session_01QnX6VHo3EJRzcKfhzBChCf