feat(paywalls-v2): port InputSingleChoice and InputOption components from iOS#3498
Draft
facumenzella wants to merge 3 commits into
Draft
feat(paywalls-v2): port InputSingleChoice and InputOption components from iOS#3498facumenzella wants to merge 3 commits into
facumenzella wants to merge 3 commits into
Conversation
Port of RevenueCat/purchases-ios#6820 Adds InputSingleChoiceComponent and InputOptionComponent to the Paywalls V2 component model and rendering pipeline: - Data model: InputSingleChoiceComponent (field_id, required, stack, overrides) and InputOptionComponent (option_id, option_value, stack, triggers, overrides) with their Partial counterparts - PaywallComponentSerializer: dispatch for "input_single_choice" and "input_option" types - BFS traversal (PaywallComponentFilterExtension) and image pre-downloader updated for both new types - PaywallComponentType.INPUT_OPTION added for interaction tracking - Style layer: InputSingleChoiceComponentStyle / InputOptionComponentStyle wrapping StackComponentStyle; fieldId propagated via StyleFactoryScope - PaywallState.Loaded.Components: selectedOptionIdsByFieldId map + update(fieldId, selectedOptionId) method for selection state - InputSingleChoiceComponentView delegates rendering to StackComponentView - InputOptionComponentView updates selection state on tap and fires a WorkflowTrigger(optionId, ON_PRESS) action - Validation error InputOptionNotInInputSingleChoice for orphaned options - JSON decode tests for all four data class types Deviation from iOS: iOS uses @EnvironmentObject (CompositionLocal) to propagate InputSingleChoiceContext. Android stores per-field selection in PaywallState.Loaded.Components.selectedOptionIdsByFieldId to comply with the project's no-new-CompositionLocal rule. Still pending: InputSingleChoiceStateTests, lint, unit test run. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hoice/InputOption - Add InputSingleChoiceStateTests: covers initial state, select, replace, deselect, and multi-field isolation for selectedOptionIdsByFieldId - Fix non-exhaustive when in OfferingToStateMapper.containsUnsupportedCondition for InputSingleChoiceComponent and InputOptionComponent - Fix non-exhaustive when in TabsComponentViewTests BFS helper for same types Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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
Android port of purchases-ios#6820.
InputSingleChoiceComponentandInputOptionComponentdata classes (with partial variants) and JSON deserializer registrationInputSingleChoiceComponentStyle/InputOptionComponentStyleandStyleFactorywiringInputSingleChoiceComponentView(delegates to its stack) andInputOptionComponentView(updatesselectedOptionIdsByFieldId, firesWorkflowTriggeron tap)PaywallState.Loaded.Components.selectedOptionIdsByFieldId— aSnapshotStateMap<String, String?>keyed byfieldId, updated viastate.update(fieldId, optionId)PaywallComponentType.INPUT_OPTIONevent type andInputOptionNotInInputSingleChoicevalidation errorPaywallComponentFilterExtension), image pre-downloader, andOfferingToStateMapper.containsUnsupportedCondition()Test plan
InputSingleChoiceComponentTests— JSON deserialization for all 4 data classesInputSingleChoiceStateTests— selection state: initial empty, select, replace, deselect (null), multi-field isolation🤖 Generated with Claude Code